Skip to content

Commit 2dc0bb6

Browse files
algomaster99woutersmeenk
authored andcommitted
feat: Add API method CtAbstractSwitch.addCaseAt (INRIA#4015)
1 parent 8c6d28e commit 2dc0bb6

File tree

4 files changed

+141
-2
lines changed

4 files changed

+141
-2
lines changed

src/main/java/spoon/reflect/code/CtAbstractSwitch.java

+11
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,17 @@ public interface CtAbstractSwitch<S> extends CtElement {
6060
@PropertySetter(role = CASE)
6161
<T extends CtAbstractSwitch<S>> T addCase(CtCase<? super S> c);
6262

63+
/**
64+
* Adds a case at the specified position.
65+
*
66+
* @param <T> type of the switch - {@link CtSwitch} or {@link CtSwitchExpression}
67+
* @param position index at which the case needs to be inserted
68+
* @param c case which has to be inserted in the switch block
69+
* @return switch block in which the case is inserted
70+
*/
71+
@PropertySetter(role = CASE)
72+
<T extends CtAbstractSwitch<S>> T addCaseAt(int position, CtCase<? super S> c);
73+
6374
/**
6475
* Removes a case;
6576
*/

src/main/java/spoon/support/reflect/code/CtSwitchExpressionImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public <T extends CtAbstractSwitch<S>> T setSelector(CtExpression<S> selector) {
7272

7373
@Override
7474
public <T extends CtAbstractSwitch<S>> T addCase(CtCase<? super S> c) {
75+
addCaseAt(cases.size(), c);
76+
return (T) this;
77+
}
78+
79+
@Override
80+
public <T extends CtAbstractSwitch<S>> T addCaseAt(int position, CtCase<? super S> c) {
7581
if (c == null) {
7682
return (T) this;
7783
}
@@ -80,7 +86,7 @@ public <T extends CtAbstractSwitch<S>> T addCase(CtCase<? super S> c) {
8086
}
8187
c.setParent(this);
8288
getFactory().getEnvironment().getModelChangeListener().onListAdd(this, CASE, this.cases, c);
83-
cases.add(c);
89+
cases.add(position, c);
8490
return (T) this;
8591
}
8692

src/main/java/spoon/support/reflect/code/CtSwitchImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ public <T extends CtAbstractSwitch<S>> T setSelector(CtExpression<S> selector) {
7272

7373
@Override
7474
public <T extends CtAbstractSwitch<S>> T addCase(CtCase<? super S> c) {
75+
addCaseAt(cases.size(), c);
76+
return (T) this;
77+
}
78+
79+
@Override
80+
public <T extends CtAbstractSwitch<S>> T addCaseAt(int position, CtCase<? super S> c) {
7581
if (c == null) {
7682
return (T) this;
7783
}
@@ -80,7 +86,7 @@ public <T extends CtAbstractSwitch<S>> T addCase(CtCase<? super S> c) {
8086
}
8187
c.setParent(this);
8288
getFactory().getEnvironment().getModelChangeListener().onListAdd(this, CASE, this.cases, c);
83-
cases.add(c);
89+
cases.add(position, c);
8490
return (T) this;
8591
}
8692

src/test/java/spoon/test/model/SwitchCaseTest.java

+116
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static org.junit.jupiter.api.Assertions.assertFalse;
1414
import static org.junit.jupiter.api.Assertions.assertNull;
1515
import static org.junit.jupiter.api.Assertions.assertSame;
16+
import static org.junit.jupiter.api.Assertions.assertThrows;
1617
import static org.junit.jupiter.api.Assertions.assertTrue;
1718
import static spoon.testing.utils.ModelUtils.build;
1819
import static spoon.testing.utils.ModelUtils.createFactory;
@@ -31,6 +32,7 @@
3132
import spoon.reflect.code.CaseKind;
3233
import spoon.reflect.code.CtBreak;
3334
import spoon.reflect.code.CtCase;
35+
import spoon.reflect.code.CtExpression;
3436
import spoon.reflect.code.CtIf;
3537
import spoon.reflect.code.CtLiteral;
3638
import spoon.reflect.code.CtLocalVariable;
@@ -249,4 +251,118 @@ public void testJava14yield() {
249251
}
250252
}
251253

254+
@Nested
255+
class InsertCaseInSwitch {
256+
@DisplayName("cases should be inserted at the correct position")
257+
@Test
258+
public void test_addCaseAt_addsCaseAtSpecifiedPositionInSwitch() {
259+
// contract: case should be added at the specified position in `CtSwitch`
260+
Factory factory = new Launcher().getFactory();
261+
262+
CtSwitch<Integer> switchBlock = factory.createSwitch();
263+
CtExpression<Integer> switchSelector = factory.createCodeSnippetExpression("x");
264+
switchBlock.setSelector(switchSelector);
265+
266+
CtBreak ctBreak = factory.createBreak();
267+
268+
CtCase<Integer> first = factory.createCase();
269+
CtExpression<Integer> firstExpression = factory.createCodeSnippetExpression("1");
270+
first.addCaseExpression(firstExpression);
271+
first.setCaseKind(CaseKind.COLON);
272+
first.addStatement(ctBreak);
273+
274+
CtCase<Integer> second = factory.createCase();
275+
CtExpression<Integer> secondExpression = factory.createCodeSnippetExpression("2");
276+
second.addCaseExpression(secondExpression);
277+
second.setCaseKind(CaseKind.COLON);
278+
second.addStatement(ctBreak);
279+
280+
CtCase<Integer> third = factory.createCase();
281+
third.setCaseKind(CaseKind.COLON);
282+
third.addStatement(ctBreak);
283+
284+
switchBlock.addCaseAt(0, third);
285+
switchBlock.addCaseAt(0,first);
286+
switchBlock.addCaseAt(1, second);
287+
288+
assertEquals(Arrays.asList(first, second, third), switchBlock.getCases());
289+
}
290+
291+
@DisplayName("should throw IndexOutOfBounds exception")
292+
@Test
293+
public void test_addCaseAt_throwsIndexOutOfBoundsException_whenPositionIsOutOfBounds() {
294+
// contract: `addCaseAt` should throw an out of bounds exception when the the specified position is out of
295+
// bounds of the case collection
296+
Factory factory = new Launcher().getFactory();
297+
298+
CtSwitch<Integer> switchBlock = factory.createSwitch();
299+
CtExpression<Integer> switchSelector = factory.createCodeSnippetExpression("x");
300+
switchBlock.setSelector(switchSelector);
301+
302+
CtCase<Integer> onlyCase = factory.createCase();
303+
CtBreak caseStatement = factory.createBreak();
304+
onlyCase.setCaseKind(CaseKind.COLON);
305+
onlyCase.addStatement(caseStatement);
306+
307+
assertThrows(IndexOutOfBoundsException.class, () -> switchBlock.addCaseAt(5, onlyCase));
308+
}
309+
}
310+
311+
@Nested
312+
class InsertCaseInSwitchExpression {
313+
@DisplayName("cases should be inserted at the correct position")
314+
@Test
315+
public void test_addCaseAt_addsCaseAtSpecifiedPositionInSwitchExpression() {
316+
// contract: case should be added at the specified position in `CtSwitchExpression`
317+
Factory factory = new Launcher().getFactory();
318+
319+
CtSwitchExpression<Integer, Integer> switchExpression = factory.createSwitchExpression();
320+
CtExpression<Integer> switchSelector = factory.createCodeSnippetExpression("x");
321+
switchExpression.setSelector(switchSelector);
322+
323+
CtCase<Integer> first = factory.createCase();
324+
CtExpression<Integer> firstExpression = factory.createCodeSnippetExpression("1");
325+
CtStatement firstStatement = factory.createCodeSnippetStatement("1");
326+
first.addCaseExpression(firstExpression);
327+
first.setCaseKind(CaseKind.ARROW);
328+
first.addStatement(firstStatement);
329+
330+
CtCase<Integer> second = factory.createCase();
331+
CtExpression<Integer> secondExpression = factory.createCodeSnippetExpression("2");
332+
CtStatement secondStatement = factory.createCodeSnippetStatement("2");
333+
second.addCaseExpression(secondExpression);
334+
second.setCaseKind(CaseKind.ARROW);
335+
second.addStatement(secondStatement);
336+
337+
CtCase<Integer> third = factory.createCase();
338+
CtStatement thirdStatement = factory.createCodeSnippetStatement("3");
339+
third.setCaseKind(CaseKind.ARROW);
340+
third.addStatement(thirdStatement);
341+
342+
switchExpression.addCaseAt(0, third);
343+
switchExpression.addCaseAt(0,first);
344+
switchExpression.addCaseAt(1, second);
345+
346+
assertEquals(Arrays.asList(first, second, third), switchExpression.getCases());
347+
}
348+
349+
@DisplayName("should throw IndexOutOfBounds exception")
350+
@Test
351+
public void test_addCaseAt_throwsIndexOutOfBoundsException_whenPositionIsOutOfBounds() {
352+
// contract: `addCaseAt` should throw an out of bounds exception when the the specified position is out of
353+
// bounds of the case collection
354+
Factory factory = new Launcher().getFactory();
355+
356+
CtSwitchExpression<Integer, Integer> switchExpression = factory.createSwitchExpression();
357+
CtExpression<Integer> switchSelector = factory.createCodeSnippetExpression("x");
358+
switchExpression.setSelector(switchSelector);
359+
360+
CtCase<Integer> onlyCase = factory.createCase();
361+
CtStatement caseStatement = factory.createCodeSnippetStatement("5");
362+
onlyCase.setCaseKind(CaseKind.ARROW);
363+
onlyCase.addStatement(caseStatement);
364+
365+
assertThrows(IndexOutOfBoundsException.class, () -> switchExpression.addCaseAt(3, onlyCase));
366+
}
367+
}
252368
}

0 commit comments

Comments
 (0)