Skip to content

Commit f92897a

Browse files
authored
SONARPY-2140 add containsSpreadOperator to Expressions (#1971)
1 parent d79830f commit f92897a

File tree

2 files changed

+28
-0
lines changed

2 files changed

+28
-0
lines changed

python-checks/src/main/java/org/sonar/python/checks/utils/Expressions.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import javax.annotation.Nullable;
3333
import org.sonar.plugins.python.api.symbols.Symbol;
3434
import org.sonar.plugins.python.api.symbols.Usage;
35+
import org.sonar.plugins.python.api.tree.Argument;
3536
import org.sonar.plugins.python.api.tree.AssignmentStatement;
3637
import org.sonar.plugins.python.api.tree.CallExpression;
3738
import org.sonar.plugins.python.api.tree.DictionaryLiteral;
@@ -379,4 +380,8 @@ public static boolean isGenericTypeAnnotation(Expression expression) {
379380
.filter(TYPE_VAR_FQN::equals)
380381
.isPresent();
381382
}
383+
384+
public static boolean containsSpreadOperator(List<Argument> arguments) {
385+
return arguments.stream().anyMatch(UnpackingExpression.class::isInstance);
386+
}
382387
}

python-checks/src/test/java/org/sonar/python/checks/utils/ExpressionsTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
import java.util.ArrayList;
2323
import java.util.List;
2424
import org.junit.jupiter.api.Test;
25+
import org.sonar.plugins.python.api.tree.Argument;
2526
import org.sonar.plugins.python.api.tree.BaseTreeVisitor;
27+
import org.sonar.plugins.python.api.tree.CallExpression;
2628
import org.sonar.plugins.python.api.tree.Expression;
2729
import org.sonar.plugins.python.api.tree.FileInput;
2830
import org.sonar.plugins.python.api.tree.Name;
@@ -37,6 +39,7 @@
3739
import org.sonar.python.tree.TreeUtils;
3840

3941
import static org.assertj.core.api.Assertions.assertThat;
42+
import static org.sonar.python.checks.utils.Expressions.containsSpreadOperator;
4043
import static org.sonar.python.checks.utils.Expressions.getAssignedName;
4144
import static org.sonar.python.checks.utils.Expressions.isFalsy;
4245
import static org.sonar.python.checks.utils.Expressions.isTruthy;
@@ -213,6 +216,26 @@ void unescape_string_element_invalid_escape_sequences() {
213216

214217
}
215218

219+
@Test
220+
void testContainsSpreadOperator() {
221+
assertThat(containsSpreadOperator(args("some(**some_dict)"))).isTrue();
222+
assertThat(containsSpreadOperator(args("some(**{})"))).isTrue();
223+
assertThat(containsSpreadOperator(args("some(1, test=True, **some_dict)"))).isTrue();
224+
assertThat(containsSpreadOperator(args("some(*some_list)"))).isTrue();
225+
assertThat(containsSpreadOperator(args("some(*[])"))).isTrue();
226+
assertThat(containsSpreadOperator(args("some(1, test=True, *some_list)"))).isTrue();
227+
228+
229+
assertThat(containsSpreadOperator(args("some(1, test=True)"))).isFalse();
230+
assertThat(containsSpreadOperator(args("some()"))).isFalse();
231+
}
232+
233+
private List<Argument> args(String source) {
234+
Expression callExpr = exp(source);
235+
assertThat(callExpr).isInstanceOf(CallExpression.class);
236+
return ((CallExpression) callExpr).arguments();
237+
}
238+
216239
private StringElement stringElement(String source) {
217240
return stringLiteral(source).stringElements().get(0);
218241
}

0 commit comments

Comments
 (0)