-
Notifications
You must be signed in to change notification settings - Fork 97
Sonarpy 668 #698
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sonarpy 668 #698
Conversation
|
In order to make the mapping of issues in the original test projects to the implementing methods a bit easier, here is the list of triples (original.py / extractedTest.py / implementingMethod): |
guillaume-dequenne
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I'd recommend using Tree#is to test the Kind of nodes rather than testing the instance.
The Kind is generally what we base our assumptions on (we sometimes use the instance but it's not the usual way) and is the strongest guarantee we have, as some different kinds might be linked to the same interface. I didn't flag every cast/test instance to avoid the noise, but I believe it might be worth to reconsider their usage nonetheless.
Also, while I wouldn't want to discourage you from using a functional style, I think some parts might be a bit more readable (at least due to consistency with the style used in the rest of the project) if written in a more idiomatic style (cf for instance the snippets I suggest).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You used the Python specific key here. You should be using the top-level RSPEC key instead (S4502). I believe that's why you had missing information in the generated metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, 4502 worked a bit better, but the tags still had to be converted to lowercase manually (otherwise, PythonRuleRepositoryTest complained about "Flask" and "Django")
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would mean it's an issue with the rule as defined in Jira: https://jira.sonarsource.com/browse/RSPEC-5792. I guess in those cases you can ping whoever created the RSPEC to notify the problem and update it (otherwise we would have to manually update each time we update metadata)
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we need those as I'd prefer going for a test on Tree#is and then a direct cast rather than testing the possibility of a cast (as different Tree.Kind could have the same underlying interface).
python-checks/src/main/java/org/sonar/python/checks/CsrfDisabledCheck.java
Outdated
Show resolved
Hide resolved
…some null checks; fix coverage
… on interfaces only.
c7531f9 to
5218093
Compare
guillaume-dequenne
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still a few comments/nitpicks, I'm not convinced we need the checkedCast methods and I think they can be replaced by something simpler. But I'd like your opinion @andrea-guarino-sonarsource on that because maybe they have their place in a util class as well.
| * If the value has the specified tree-<code>kind</code>, it is cast as an instance of the specified class, and | ||
| * returned in a non-empty <code>Optional</code>. Otherwise, returns an empty <code>Optional</code>. | ||
| */ | ||
| private static <A extends Tree, B extends Tree> Optional<B> checkedCast(Tree.Kind kind, Class<B> c, @Nullable A a) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Personally I think we shouldn't need those methods.
Why not use something like .filter(x -> x.is(Kind.Y)).map(Y.class::cast) instead of defining these methods? It feels more idiomatic.
At any rate if we're going to use those methods, I believe they should be in a util class where other checks will be able to benefit from them. What do you think @andrea-guarino-sonarsource ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well... Optional.ofNullable(x).filter(x -> x.is(Kind.YK)).map(Y.class::cast) still looked a bit noisy, especially since it occurred over and over again in several places.
If the method definitions themselves are too distracting, I can inline them for now.
I think there is no need extracting them into an Util class, stuff like that is easy to introduce, but hard to get rid of. If anyone else wants to discuss how one might cut down the noise from the checks and casts, maybe we could collect some proposals at some later point.
| private static void metaCheck(SubscriptionContext subscriptionContext) { | ||
| ClassDef classDef = (ClassDef) subscriptionContext.syntaxNode(); | ||
| boolean isMetaClass = "Meta".equals(classDef.name().name()); | ||
| if (!isMetaClass) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick but I believe you can inline this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inlined
|
|
||
| /** Checks whether the expression is a string literal with value exactly equal to <code>s</code>. */ | ||
| @SuppressWarnings("SameParameterValue") | ||
| private static Predicate<Expression> isStringEqual(String s) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this method? I believe you could pass the predicate directly to isStringSatisfying, knowing the method is called only once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inlined
| if (expr.is(Tree.Kind.STRING_LITERAL)) { | ||
| return pred.test(((StringLiteral) expr).trimmedQuotesValue()); | ||
| } else { | ||
| return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nitpick but I believe the else is not needed since you return directly from the if anyway.
| /** Checks that an expression is a list literal with at least one entry satisfying the predicate. */ | ||
| private static Predicate<Expression> isListAnyMatch(Predicate<Expression> pred) { | ||
| return expr -> Optional.ofNullable(expr) | ||
| .filter(ListLiteral.class::isInstance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can use .filter(l -> l.is(Tree.Kind.LIST_LITERAL)) instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, true, missed that one.
| /** Looks for <code>'csrf': False</code> and similar settings in a dictionary. */ | ||
| private static Optional<Expression> searchForBadCsrfSettingInDictionary(DictionaryLiteral dict) { | ||
| return dict.elements().stream() | ||
| .filter(KeyValuePair.class::isInstance) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here as well I believe we can rely on Kind.
|
Kudos, SonarQube Quality Gate passed! |
andrea-guarino-sonarsource
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
GitOrigin-RevId: bd10c810f495da6214dba9cf8281d36cf7262583
Two differences to the original formulation of the ticket:
The 'defaultSeverity' was missing in the automatically generated S5792.json, I've set it to 'Major' for now. Also, the tags were changed to lowercase in the same JSON file.