Skip to content

Commit 790bca8

Browse files
algomaster99woutersmeenk
authored andcommitted
feat: Add CtExecutable.addParameterAt (INRIA#3902)
1 parent 4c3dbb1 commit 790bca8

File tree

8 files changed

+173
-2
lines changed

8 files changed

+173
-2
lines changed

src/main/java/spoon/reflect/declaration/CtAnonymousExecutable.java

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public interface CtAnonymousExecutable extends CtExecutable<Void>, CtTypeMember
4242
@UnsettableProperty
4343
<T extends CtExecutable<Void>> T addParameter(CtParameter<?> parameter);
4444

45+
@Override
46+
@UnsettableProperty
47+
<T extends CtExecutable<Void>> T addParameterAt(int position, CtParameter<?> parameter);
48+
4549
@Override
4650
@UnsettableProperty
4751
<T extends CtExecutable<Void>> T addThrownType(CtTypeReference<? extends Throwable> throwType);

src/main/java/spoon/reflect/declaration/CtExecutable.java

+10
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ public interface CtExecutable<R> extends CtNamedElement, CtTypedElement<R>, CtBo
6868
@PropertySetter(role = PARAMETER)
6969
<T extends CtExecutable<R>> T addParameter(CtParameter<?> parameter);
7070

71+
/**
72+
* Add a parameter at a specific position in the executable.
73+
*
74+
* @param position index where the `parameter` needs to be inserted
75+
* @param parameter parameter to be inserted
76+
* @return an object or sub-type of {@link CtExecutable}
77+
*/
78+
@PropertySetter(role = PARAMETER)
79+
<T extends CtExecutable<R>> T addParameterAt(int position, CtParameter<?> parameter);
80+
7181
/**
7282
* Remove a parameter for this executable
7383
*

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

+7-1
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ public <C extends CtExecutable<T>> C setParameters(List<CtParameter<?>> params)
188188

189189
@Override
190190
public <C extends CtExecutable<T>> C addParameter(CtParameter<?> parameter) {
191+
addParameterAt(parameters.size(), parameter);
192+
return (C) this;
193+
}
194+
195+
@Override
196+
public <C extends CtExecutable<T>> C addParameterAt(int position, CtParameter<?> parameter) {
191197
if (parameter == null) {
192198
return (C) this;
193199
}
@@ -196,7 +202,7 @@ public <C extends CtExecutable<T>> C addParameter(CtParameter<?> parameter) {
196202
}
197203
parameter.setParent(this);
198204
getFactory().getEnvironment().getModelChangeListener().onListAdd(this, PARAMETER, this.parameters, parameter);
199-
parameters.add(parameter);
205+
parameters.add(position, parameter);
200206
return (C) this;
201207
}
202208

src/main/java/spoon/support/reflect/declaration/CtAnonymousExecutableImpl.java

+7
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ public CtExecutable addParameter(CtParameter parameter) {
116116
return this;
117117
}
118118

119+
@Override
120+
@UnsettableProperty
121+
public CtExecutable addParameterAt(int position, CtParameter parameter) {
122+
// unsettable property
123+
return this;
124+
}
125+
119126
@Override
120127
@UnsettableProperty
121128
public boolean removeParameter(CtParameter parameter) {

src/main/java/spoon/support/reflect/declaration/CtExecutableImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,12 @@ public <T extends CtExecutable<R>> T setParameters(List<CtParameter<?>> paramete
104104

105105
@Override
106106
public <T extends CtExecutable<R>> T addParameter(CtParameter<?> parameter) {
107+
addParameterAt(parameters.size(), parameter);
108+
return (T) this;
109+
}
110+
111+
@Override
112+
public <T extends CtExecutable<R>> T addParameterAt(int position, CtParameter<?> parameter) {
107113
if (parameter == null) {
108114
return (T) this;
109115
}
@@ -112,7 +118,7 @@ public <T extends CtExecutable<R>> T addParameter(CtParameter<?> parameter) {
112118
}
113119
parameter.setParent(this);
114120
getFactory().getEnvironment().getModelChangeListener().onListAdd(this, PARAMETER, this.parameters, parameter);
115-
parameters.add(parameter);
121+
parameters.add(position, parameter);
116122
return (T) this;
117123
}
118124

src/test/java/spoon/test/constructor/ConstructorTest.java

+46
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import spoon.reflect.code.CtConstructorCall;
2424
import spoon.reflect.declaration.CtClass;
2525
import spoon.reflect.declaration.CtConstructor;
26+
import spoon.reflect.declaration.CtParameter;
2627
import spoon.reflect.declaration.CtTypeParameter;
2728
import spoon.reflect.factory.Factory;
2829
import spoon.reflect.reference.CtIntersectionTypeReference;
@@ -35,12 +36,16 @@
3536
import spoon.testing.utils.ModelUtils;
3637

3738
import java.util.ArrayList;
39+
import java.util.Arrays;
3840
import java.util.List;
3941
import java.util.Set;
4042
import java.util.stream.Collectors;
4143

44+
import static org.hamcrest.CoreMatchers.equalTo;
45+
import static org.hamcrest.MatcherAssert.assertThat;
4246
import static org.junit.Assert.assertEquals;
4347
import static org.junit.Assert.assertFalse;
48+
import static org.junit.Assert.assertThrows;
4449
import static org.junit.Assert.assertTrue;
4550
import static org.junit.Assert.fail;
4651
import static spoon.testing.utils.ModelUtils.canBeBuilt;
@@ -158,4 +163,45 @@ private void assertIntersectionTypeInConstructor(CtTypeReference<?> boundingType
158163
assertEquals("Serializable", bounds.get(1).getSimpleName());
159164
assertEquals(1, bounds.get(1).getAnnotations().size());
160165
}
166+
167+
@Test
168+
public void test_addParameterAt_addsParameterToSpecifiedPosition() {
169+
// contract: the parameter should be added at the specified position
170+
Factory factory = new Launcher().getFactory();
171+
172+
CtConstructor<?> constructor = factory.createConstructor();
173+
174+
CtParameter<String> first = factory.createParameter();
175+
CtTypeReference<String> firstType = factory.Type().stringType();
176+
first.setSimpleName("x");
177+
first.setType(firstType);
178+
179+
CtParameter<Integer> second = factory.createParameter();
180+
CtTypeReference<Integer> secondType = factory.Type().integerType();
181+
second.setSimpleName("y");
182+
second.setType(secondType);
183+
184+
CtParameter<Boolean> third = factory.createParameter();
185+
CtTypeReference<Boolean> thirdType = factory.Type().booleanType();
186+
third.setSimpleName("z");
187+
third.setType(thirdType);
188+
189+
constructor.addParameterAt(0, second);
190+
constructor.addParameterAt(1, third);
191+
constructor.addParameterAt(0, first);
192+
193+
assertThat(constructor.getParameters(), equalTo(Arrays.asList(first, second, third)));
194+
}
195+
196+
@Test
197+
public void test_addParameterAt_throwsOutOfBoundsException_whenPositionIsOutOfBounds() {
198+
// contract: `addParameterAt` should throw an out of bounds exception when the specified position is out of
199+
// bounds of the parameter collection
200+
Factory factory = new Launcher().getFactory();
201+
CtConstructor<?> constructor = factory.createConstructor();
202+
CtParameter<?> paramater = factory.createParameter();
203+
204+
assertThrows(IndexOutOfBoundsException.class,
205+
() -> constructor.addParameterAt(2, paramater));
206+
}
161207
}

src/test/java/spoon/test/lambda/LambdaTest.java

+45
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,19 @@
5454
import spoon.testing.utils.ModelUtils;
5555

5656
import java.io.File;
57+
import java.util.Arrays;
5758
import java.util.List;
5859
import java.util.function.Consumer;
5960
import java.util.function.Predicate;
6061
import java.util.stream.Collectors;
6162

63+
import static org.hamcrest.CoreMatchers.equalTo;
64+
import static org.hamcrest.MatcherAssert.assertThat;
6265
import static org.junit.Assert.assertEquals;
6366
import static org.junit.Assert.assertNotNull;
6467
import static org.junit.Assert.assertNull;
6568
import static org.junit.Assert.assertSame;
69+
import static org.junit.Assert.assertThrows;
6670
import static org.junit.Assert.assertTrue;
6771
import static org.junit.Assert.fail;
6872
import static spoon.testing.utils.ModelUtils.canBeBuilt;
@@ -536,4 +540,45 @@ public void testGetDeclarationOnTypeParameterFromLambda() {
536540
}
537541
}
538542
}
543+
544+
@Test
545+
public void test_addParameterAt_addsParameterToSpecifiedPosition() {
546+
// contract: the parameter should be added at the specified position
547+
Factory factory = new Launcher().getFactory();
548+
549+
CtLambda<?> lambda = factory.createLambda();
550+
551+
CtParameter<String> first = factory.createParameter();
552+
CtTypeReference<String> firstType = factory.Type().stringType();
553+
first.setSimpleName("x");
554+
first.setType(firstType);
555+
556+
CtParameter<Integer> second = factory.createParameter();
557+
CtTypeReference<Integer> secondType = factory.Type().integerType();
558+
second.setSimpleName("y");
559+
second.setType(secondType);
560+
561+
CtParameter<Boolean> third = factory.createParameter();
562+
CtTypeReference<Boolean> thirdType = factory.Type().booleanType();
563+
third.setSimpleName("z");
564+
third.setType(thirdType);
565+
566+
lambda.addParameterAt(0, second);
567+
lambda.addParameterAt(1, third);
568+
lambda.addParameterAt(0, first);
569+
570+
assertThat(lambda.getParameters(), equalTo(Arrays.asList(first, second, third)));
571+
}
572+
573+
@Test
574+
public void test_addParameterAt_throwsOutOfBoundsException_whenPositionIsOutOfBounds() {
575+
// contract: `addParameterAt` should throw an out of bounds exception when the specified position is out of
576+
// bounds of the parameter collection
577+
Factory factory = new Launcher().getFactory();
578+
CtLambda<?> lamda = factory.createLambda();
579+
CtParameter<?> paramater = factory.createParameter();
580+
581+
assertThrows(IndexOutOfBoundsException.class,
582+
() -> lamda.addParameterAt(2, paramater));
583+
}
539584
}

src/test/java/spoon/test/method/MethodTest.java

+47
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,26 @@
2020
import spoon.Launcher;
2121
import spoon.reflect.declaration.CtClass;
2222
import spoon.reflect.declaration.CtMethod;
23+
import spoon.reflect.declaration.CtParameter;
2324
import spoon.reflect.declaration.CtType;
2425
import spoon.reflect.declaration.ModifierKind;
2526
import spoon.reflect.factory.Factory;
27+
import spoon.reflect.reference.CtTypeReference;
2628
import spoon.reflect.visitor.filter.NamedElementFilter;
2729
import spoon.test.delete.testclasses.Adobada;
2830
import spoon.test.method.testclasses.Methods;
2931
import spoon.test.method.testclasses.Tacos;
3032

3133
import java.util.ArrayList;
34+
import java.util.Arrays;
3235
import java.util.ConcurrentModificationException;
3336
import java.util.HashSet;
3437
import java.util.Set;
3538

39+
import static org.hamcrest.CoreMatchers.equalTo;
40+
import static org.hamcrest.MatcherAssert.assertThat;
3641
import static org.junit.Assert.assertEquals;
42+
import static org.junit.Assert.assertThrows;
3743
import static org.junit.Assert.assertTrue;
3844
import static org.junit.Assert.fail;
3945
import static spoon.testing.utils.ModelUtils.build;
@@ -133,4 +139,45 @@ public void testGetAllMethodsAdaptingType() {
133139

134140
assertTrue(compareFound);
135141
}
142+
143+
@Test
144+
public void test_addParameterAt_addsParameterToSpecifiedPosition() {
145+
// contract: the parameter should be added at the specified position
146+
Factory factory = new Launcher().getFactory();
147+
148+
CtMethod<?> method = factory.createMethod();
149+
150+
CtParameter<String> first = factory.createParameter();
151+
CtTypeReference<String> firstType = factory.Type().stringType();
152+
first.setSimpleName("x");
153+
first.setType(firstType);
154+
155+
CtParameter<Integer> second = factory.createParameter();
156+
CtTypeReference<Integer> secondType = factory.Type().integerType();
157+
second.setSimpleName("y");
158+
second.setType(secondType);
159+
160+
CtParameter<Boolean> third = factory.createParameter();
161+
CtTypeReference<Boolean> thirdType = factory.Type().booleanType();
162+
third.setSimpleName("z");
163+
third.setType(thirdType);
164+
165+
method.addParameterAt(0, second);
166+
method.addParameterAt(1, third);
167+
method.addParameterAt(0, first);
168+
169+
assertThat(method.getParameters(), equalTo(Arrays.asList(first, second, third)));
170+
}
171+
172+
@Test
173+
public void test_addParameterAt_throwsOutOfBoundsException_whenPositionIsOutOfBounds() {
174+
// contract: `addParameterAt` should throw an out of bounds exception when the specified position is out of
175+
// bounds of the parameter collection
176+
Factory factory = new Launcher().getFactory();
177+
CtMethod<?> method = factory.createMethod();
178+
CtParameter<?> paramater = factory.createParameter();
179+
180+
assertThrows(IndexOutOfBoundsException.class,
181+
() -> method.addParameterAt(2, paramater));
182+
}
136183
}

0 commit comments

Comments
 (0)