|
43 | 43 | import org.sonar.python.types.TypeInference.MemberAccess; |
44 | 44 |
|
45 | 45 | import static org.sonar.plugins.python.api.tree.Tree.Kind.ASSIGNMENT_STMT; |
46 | | -import static org.sonar.plugins.python.api.tree.Tree.Kind.CALL_EXPR; |
47 | 46 | import static org.sonar.plugins.python.api.tree.Tree.Kind.NAME; |
48 | 47 | import static org.sonar.plugins.python.api.tree.Tree.Kind.REGULAR_ARGUMENT; |
49 | 48 |
|
@@ -81,36 +80,42 @@ public void updateProgramState(Tree element, ProgramState programState) { |
81 | 80 | handleAssignment(assignment, state); |
82 | 81 | // update lhs |
83 | 82 | assignment.lhsExpressions().forEach(lhs -> updateTree(lhs, state)); |
84 | | - } else if (isIsInstanceCall(element)) { |
85 | | - Symbol firstArgumentSymbol = getFirstArgumentSymbol(((CallExpression) element), state); |
86 | | - if (firstArgumentSymbol != null) { |
87 | | - state.setTypes(firstArgumentSymbol, Collections.singleton(InferredTypes.anyType())); |
88 | | - } |
89 | | - updateTree(element, state); |
90 | 83 | } else { |
| 84 | + element.accept(new IsInstanceVisitor(state)); |
91 | 85 | updateTree(element, state); |
92 | 86 | } |
93 | 87 | } |
94 | 88 |
|
95 | | - private static boolean isIsInstanceCall(Tree tree) { |
96 | | - if (tree.is(CALL_EXPR)) { |
97 | | - CallExpression callExpression = (CallExpression) tree; |
| 89 | + private static class IsInstanceVisitor extends BaseTreeVisitor { |
| 90 | + private final TypeInferenceProgramState state; |
| 91 | + |
| 92 | + public IsInstanceVisitor(TypeInferenceProgramState state) { |
| 93 | + this.state = state; |
| 94 | + } |
| 95 | + |
| 96 | + @Override |
| 97 | + public void visitCallExpression(CallExpression callExpression) { |
98 | 98 | Symbol calleeSymbol = callExpression.calleeSymbol(); |
99 | | - return calleeSymbol != null && "isinstance".equals(calleeSymbol.fullyQualifiedName()) && callExpression.arguments().size() == 2; |
| 99 | + if (calleeSymbol != null && "isinstance".equals(calleeSymbol.fullyQualifiedName()) && callExpression.arguments().size() == 2) { |
| 100 | + Symbol firstArgumentSymbol = getFirstArgumentSymbol(callExpression); |
| 101 | + if (firstArgumentSymbol != null) { |
| 102 | + state.setTypes(firstArgumentSymbol, Collections.singleton(InferredTypes.anyType())); |
| 103 | + } |
| 104 | + } |
| 105 | + super.visitCallExpression(callExpression); |
100 | 106 | } |
101 | | - return false; |
102 | | - } |
103 | 107 |
|
104 | | - @CheckForNull |
105 | | - private static Symbol getFirstArgumentSymbol(CallExpression callExpression, TypeInferenceProgramState state) { |
106 | | - Argument argument = callExpression.arguments().get(0); |
107 | | - if (argument.is(REGULAR_ARGUMENT) && ((RegularArgument) argument).expression().is(NAME)) { |
108 | | - Name variableName = (Name) ((RegularArgument) argument).expression(); |
109 | | - if (state.getTypes(variableName.symbol()).stream().anyMatch(InferredTypes::containsDeclaredType)) { |
110 | | - return variableName.symbol(); |
| 108 | + @CheckForNull |
| 109 | + private Symbol getFirstArgumentSymbol(CallExpression callExpression) { |
| 110 | + Argument argument = callExpression.arguments().get(0); |
| 111 | + if (argument.is(REGULAR_ARGUMENT) && ((RegularArgument) argument).expression().is(NAME)) { |
| 112 | + Name variableName = (Name) ((RegularArgument) argument).expression(); |
| 113 | + if (state.getTypes(variableName.symbol()).stream().anyMatch(InferredTypes::containsDeclaredType)) { |
| 114 | + return variableName.symbol(); |
| 115 | + } |
111 | 116 | } |
| 117 | + return null; |
112 | 118 | } |
113 | | - return null; |
114 | 119 | } |
115 | 120 |
|
116 | 121 | private void updateTree(Tree tree, TypeInferenceProgramState state) { |
|
0 commit comments