Skip to content

Commit d043462

Browse files
SONARPY-2468 IgnoredPureOperationsCheck#checkExpression should reuse TypeCheckers (#2247)
1 parent 7f31e9e commit d043462

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

python-checks/src/main/java/org/sonar/python/checks/IgnoredPureOperationsCheck.java

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import java.util.Arrays;
2020
import java.util.HashSet;
21+
import java.util.Map;
2122
import java.util.Set;
23+
import java.util.stream.Collectors;
2224
import org.sonar.check.Rule;
2325
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
2426
import org.sonar.plugins.python.api.SubscriptionContext;
@@ -31,7 +33,7 @@
3133
import org.sonar.python.tree.TreeUtils;
3234
import org.sonar.python.types.v2.PythonType;
3335
import org.sonar.python.types.v2.TriBool;
34-
import org.sonar.python.types.v2.TypeChecker;
36+
import org.sonar.python.types.v2.TypeCheckBuilder;
3537

3638
@Rule(key = "S2201")
3739
public class IgnoredPureOperationsCheck extends PythonSubscriptionCheck {
@@ -278,8 +280,13 @@ public class IgnoredPureOperationsCheck extends PythonSubscriptionCheck {
278280
));
279281
}
280282

283+
private static Map<String, TypeCheckBuilder> pureFunctionsCheckers = null;
284+
private static Set<TypeCheckBuilder> pureGetitemTypesCheckers = null;
285+
private static Set<TypeCheckBuilder> pureContainsTypesCheckers = null;
286+
281287
@Override
282288
public void initialize(Context context) {
289+
context.registerSyntaxNodeConsumer(Tree.Kind.FILE_INPUT, IgnoredPureOperationsCheck::resetTypeCheckers);
283290
context.registerSyntaxNodeConsumer(Tree.Kind.EXPRESSION_STMT, ctx -> {
284291
ExpressionStatement expressionStatement = (ExpressionStatement) ctx.syntaxNode();
285292
if (TreeUtils.firstAncestor(expressionStatement, IgnoredPureOperationsCheck::isInTryBlock) != null) {
@@ -290,26 +297,31 @@ public void initialize(Context context) {
290297
});
291298
}
292299

300+
private static void resetTypeCheckers(SubscriptionContext ctx) {
301+
pureFunctionsCheckers = PURE_FUNCTIONS.stream().collect(Collectors.toMap(f -> f, f -> ctx.typeChecker().typeCheckBuilder().isTypeWithName(f)));
302+
pureGetitemTypesCheckers = PURE_GETITEM_TYPES.stream().map(f -> ctx.typeChecker().typeCheckBuilder().isTypeOrInstanceWithName(f)).collect(Collectors.toSet());
303+
pureContainsTypesCheckers = PURE_CONTAINS_TYPES.stream().map(f -> ctx.typeChecker().typeCheckBuilder().isTypeOrInstanceWithName(f)).collect(Collectors.toSet());
304+
}
305+
293306
private static void checkExpression(SubscriptionContext ctx, Expression expression) {
294-
TypeChecker typeChecker = ctx.typeChecker();
295307
if (expression.is(Tree.Kind.CALL_EXPR)) {
296308
CallExpression callExpression = (CallExpression) expression;
297309
PythonType pythonType = callExpression.callee().typeV2();
298-
PURE_FUNCTIONS.stream()
299-
.filter(f -> typeChecker.typeCheckBuilder().isTypeWithName(f).check(pythonType).equals(TriBool.TRUE))
310+
pureFunctionsCheckers.entrySet().stream()
311+
.filter(c -> c.getValue().check(pythonType).equals(TriBool.TRUE))
300312
.findFirst()
301-
.ifPresent(result -> ctx.addIssue(callExpression.callee(), String.format(MESSAGE_FORMAT, result)));
313+
.ifPresent(result -> ctx.addIssue(callExpression.callee(), String.format(MESSAGE_FORMAT, result.getKey())));
302314
} else if (expression.is(Tree.Kind.SUBSCRIPTION)) {
303315
SubscriptionExpression subscriptionExpression = (SubscriptionExpression) expression;
304316
PythonType pythonType = subscriptionExpression.object().typeV2();
305-
boolean isPureGetitemType = PURE_GETITEM_TYPES.stream().anyMatch(t -> typeChecker.typeCheckBuilder().isTypeOrInstanceWithName(t).check(pythonType).equals(TriBool.TRUE));
317+
boolean isPureGetitemType = pureGetitemTypesCheckers.stream().anyMatch(c -> c.check(pythonType).equals(TriBool.TRUE));
306318
if (isPureGetitemType) {
307319
ctx.addIssue(subscriptionExpression, String.format(MESSAGE_FORMAT, "__getitem__"));
308320
}
309321
} else if (expression.is(Tree.Kind.IN)) {
310322
InExpression inExpression = (InExpression) expression;
311323
PythonType pythonType = inExpression.rightOperand().typeV2();
312-
boolean isPureContainsType = PURE_CONTAINS_TYPES.stream().anyMatch(t -> typeChecker.typeCheckBuilder().isTypeOrInstanceWithName(t).check(pythonType).equals(TriBool.TRUE));
324+
boolean isPureContainsType = pureContainsTypesCheckers.stream().anyMatch(c -> c.check(pythonType).equals(TriBool.TRUE));
313325
if (isPureContainsType) {
314326
ctx.addIssue(inExpression, String.format(MESSAGE_FORMAT, "__contains__"));
315327
}

0 commit comments

Comments
 (0)