2222import org .sonar .check .Rule ;
2323import org .sonar .plugins .python .api .PythonSubscriptionCheck ;
2424import org .sonar .plugins .python .api .SubscriptionContext ;
25- import org .sonar .plugins .python .api .symbols .Symbol ;
26- import org .sonar .plugins .python .api .symbols .Usage ;
25+ import org .sonar .plugins .python .api .symbols .v2 . SymbolV2 ;
26+ import org .sonar .plugins .python .api .symbols .v2 . UsageV2 ;
2727import org .sonar .plugins .python .api .tree .AnnotatedAssignment ;
2828import org .sonar .plugins .python .api .tree .AssignmentExpression ;
2929import org .sonar .plugins .python .api .tree .AssignmentStatement ;
3232import org .sonar .plugins .python .api .tree .Name ;
3333import org .sonar .plugins .python .api .tree .RegularArgument ;
3434import org .sonar .plugins .python .api .tree .Tree ;
35+ import org .sonar .plugins .python .api .types .v2 .matchers .TypeMatcher ;
36+ import org .sonar .plugins .python .api .types .v2 .matchers .TypeMatchers ;
3537import org .sonar .python .tree .TreeUtils ;
3638
3739@ Rule (key = "S6556" )
@@ -42,6 +44,8 @@ public class DjangoRenderContextCheck extends PythonSubscriptionCheck {
4244 private static final String RENDER_FUNCTION = "django.shortcuts.render" ;
4345 private static final String LOCALS = "locals" ;
4446 private static final String CONTEXT_KEYWORD = "context" ;
47+ private static final TypeMatcher RENDER_FUNCTION_MATCHER = TypeMatchers .withFQN (RENDER_FUNCTION );
48+ private static final TypeMatcher LOCALS_FUNCTION_MATCHER = TypeMatchers .withFQN (LOCALS );
4549
4650 private static final int MAX_RECURSION_COUNT = 5 ;
4751
@@ -52,8 +56,7 @@ public void initialize(Context context) {
5256
5357 private static void checkForDjangoRender (SubscriptionContext ctx ) {
5458 CallExpression expression = ((CallExpression ) ctx .syntaxNode ());
55- Symbol symbol = expression .calleeSymbol ();
56- if (symbol != null && RENDER_FUNCTION .equals (symbol .fullyQualifiedName ())) {
59+ if (RENDER_FUNCTION_MATCHER .isTrueFor (expression .callee (), ctx )) {
5760 checkForContextArgument (ctx , expression );
5861 }
5962 }
@@ -63,7 +66,7 @@ private static void checkForContextArgument(SubscriptionContext ctx, CallExpress
6366 if (contextArg != null ) {
6467 if (contextArg .expression ().is (Tree .Kind .CALL_EXPR )) {
6568 CallExpression maybeLocalsCall = (CallExpression ) contextArg .expression ();
66- if (isLocalsCall (maybeLocalsCall )) {
69+ if (isLocalsCall (maybeLocalsCall , ctx )) {
6770 ctx .addIssue (maybeLocalsCall , MESSAGE );
6871 }
6972 } else if (contextArg .expression ().is (Tree .Kind .NAME )) {
@@ -74,11 +77,11 @@ private static void checkForContextArgument(SubscriptionContext ctx, CallExpress
7477
7578 private static void checkIfLocalsIsAssignedToContextParameter (SubscriptionContext ctx , RegularArgument contextArg , Name maybeLocalsCall , int recursionCount ) {
7679 if (recursionCount <= MAX_RECURSION_COUNT ) {
77- Symbol contextSymbol = maybeLocalsCall .symbol ();
80+ SymbolV2 contextSymbol = maybeLocalsCall .symbolV2 ();
7881 if (contextSymbol != null ) {
7982 List <Tree > assignmentStmts = contextSymbol .usages ().stream ()
80- .filter (usage -> usage .kind () == Usage .Kind .ASSIGNMENT_LHS )
81- .map (Usage ::tree )
83+ .filter (usage -> usage .kind () == UsageV2 .Kind .ASSIGNMENT_LHS )
84+ .map (UsageV2 ::tree )
8285 .map (usage -> TreeUtils .firstAncestorOfKind (usage , Tree .Kind .ASSIGNMENT_EXPRESSION , Tree .Kind .ASSIGNMENT_STMT , Tree .Kind .ANNOTATED_ASSIGNMENT ))
8386 .filter (Objects ::nonNull )
8487 .toList ();
@@ -108,7 +111,7 @@ private static void checkIfLocalsIsCalledOrFindTheNextAncestor(SubscriptionConte
108111 int recursionCount ) {
109112 if (assignedValue .is (Tree .Kind .CALL_EXPR )) {
110113 CallExpression localsAssignment = (CallExpression ) assignedValue ;
111- if (isLocalsCall (localsAssignment )) {
114+ if (isLocalsCall (localsAssignment , ctx )) {
112115 raiseIssueLocalsIsAssigned (ctx , contextArg , assignment , localsAssignment );
113116 }
114117 } else if (assignedValue .is (Tree .Kind .NAME )) {
@@ -134,8 +137,7 @@ private static void raiseIssueLocalsIsAssigned(SubscriptionContext ctx, RegularA
134137 }
135138 }
136139
137- private static boolean isLocalsCall (CallExpression callExpression ) {
138- Symbol localsSymbol = callExpression .calleeSymbol ();
139- return localsSymbol != null && LOCALS .equals (localsSymbol .fullyQualifiedName ());
140+ private static boolean isLocalsCall (CallExpression callExpression , SubscriptionContext ctx ) {
141+ return LOCALS_FUNCTION_MATCHER .isTrueFor (callExpression .callee (), ctx );
140142 }
141143}
0 commit comments