-
Notifications
You must be signed in to change notification settings - Fork 93
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-2370 Fix FP on S5644 for generic types defined through type parameter syntax #2209
Conversation
60ac144
to
c2023cc
Compare
…arameter syntax
c2023cc
to
d2a95c3
Compare
return false; | ||
} | ||
|
||
private static Optional<Expression> isSubscriptionInClassArg(Expression subscriptionObject) { |
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 went for the quick win to fix the FP, instead of looking at migrating to V2.
return null; | ||
} | ||
|
||
private static boolean isValidSubscriptionCallExpr(CallExpression subscriptionObject, Map<LocationInFile, String> secondaries) { |
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.
could be simplified
private static boolean isValidSubscriptionCallExpr(Expression expression, Map<LocationInFile, String> secondaries) {
if (expression instanceof CallExpression callExpression
&& callExpression.calleeSymbol() instanceof FunctionSymbol functionSymbol
&& functionSymbol.isAsynchronous()) {
secondaries.put(functionSymbol.definitionLocation(), SECONDARY_MESSAGE.formatted(functionSymbol.name()));
return true;
}
return false;
}
and then no need to check for subscriptionObject.is(Tree.Kind.CALL_EXPR)
on line 56
Symbol subscriptionCalleeSymbol = subscriptionObject.calleeSymbol(); | ||
if (subscriptionCalleeSymbol != null && subscriptionCalleeSymbol.is(FUNCTION) && ((FunctionSymbol) subscriptionCalleeSymbol).isAsynchronous()) { | ||
FunctionSymbol functionSymbol = (FunctionSymbol) subscriptionCalleeSymbol; | ||
secondaries.put(functionSymbol.definitionLocation(), String.format(SECONDARY_MESSAGE, functionSymbol.name())); |
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.
String.format(SECONDARY_MESSAGE...
could be replaced with:
SECONDARY_MESSAGE.formatted(functionSymbol.name())
return false; | ||
} | ||
|
||
private static Optional<Expression> isSubscriptionInClassArg(Expression subscriptionObject) { |
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.
could simply return a boolean:
private static boolean isSubscriptionInClassArg(Expression subscriptionObject) {
return Optional.ofNullable(((ClassDef) TreeUtils.firstAncestorOfKind(subscriptionObject, Tree.Kind.CLASSDEF)))
.map(ClassDef::args)
.map(ArgList::arguments)
.stream()
.flatMap(Collection::stream)
.flatMap(TreeUtils.toStreamInstanceOfMapper(RegularArgument.class))
.map(RegularArgument::expression)
.flatMap(TreeUtils.toStreamInstanceOfMapper(SubscriptionExpression.class))
.map(SubscriptionExpression::object)
.anyMatch(subscriptionObject::equals);
}
|
||
class MyGenericClass[T]: ... | ||
|
||
class MyGenericSubType(MyGenericClass[str]): ... # FP S5644 |
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: add empty line in the end of the file
if (isSubscriptionInClassArg(subscriptionObject).isPresent()) { | ||
return true; | ||
} | ||
|
||
return canHaveMethod(symbol, requiredMethod, classRequiredMethod); |
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.
could be simplified:
return isSubscriptionInClassArg(subscriptionObject) || canHaveMethod(symbol, requiredMethod, classRequiredMethod);
return true; | ||
} | ||
if (symbol.is(FUNCTION, CLASS)) { | ||
secondaries.put(symbol.is(FUNCTION) ? ((FunctionSymbol) symbol).definitionLocation() : ((ClassSymbol) symbol).definitionLocation(), |
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.
It will be easier to read if the location calculation will be extended and assigned to a local variable
} | ||
if (symbol.is(FUNCTION, CLASS)) { | ||
secondaries.put(symbol.is(FUNCTION) ? ((FunctionSymbol) symbol).definitionLocation() : ((ClassSymbol) symbol).definitionLocation(), | ||
String.format(SECONDARY_MESSAGE, symbol.name())); |
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.
could be replaced with
SECONDARY_MESSAGE.formatter(symbol.name())
} | ||
|
||
if (subscriptionObject instanceof HasSymbol hasSymbol) { |
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.
this if
could be moved to be a part of isValidSubscriptionSymbol
secondaries.put(functionSymbol.definitionLocation(), String.format(SECONDARY_MESSAGE, functionSymbol.name())); | ||
return false; | ||
} | ||
if (subscriptionObject.is(Tree.Kind.CALL_EXPR) && isValidSubscriptionCallExpr((CallExpression) subscriptionObject, secondaries)) { |
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.
seems that methods isValidSubscriptionCallExpr
and isValidSubscriptionSymbol
both have inverted logic to the isValidSubscription
, so I'd suggest to rename them to isInvalid...
secondaries.put(symbol.is(FUNCTION) ? | ||
((FunctionSymbol) symbol).definitionLocation() : ((ClassSymbol) symbol).definitionLocation(), String.format(SECONDARY_MESSAGE, symbol.name())); | ||
return canHaveMethod(symbol, requiredMethod, classRequiredMethod); | ||
var isValidSubscriptionSymbol = isValidSubscriptionSymbol(hasSymbol, subscriptionObject, secondaries, requiredMethod, classRequiredMethod); |
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.
to get rid of the cases where we check boolead for a null
I'd probably will suggest to split the method to two methods:
- get a symbol to validate (do the filtering if validation is not needed here)
- validation itself returning simple
boolean
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 looks good, some comments need to be addressed
96d04ad
to
a5ad4a9
Compare
a5ad4a9
to
5d17b41
Compare
} | ||
|
||
var symbol = TreeUtils.getSymbolFromTree(subscriptionObject) | ||
.filter(s -> s.is(FUNCTION, CLASS)) |
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.
as discussed - the previous logic was to return true
even if a symbol is not a function or a class but has an fqn
starting from typing
or collection
, need to revisit this condition
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.
Looks good! Thanks for the changes. As discussed, the potential problem that needs to be solved is the validation of non-function
and non-class
symbols from typing
or collections
modules
fee7634
to
babb9e8
Compare
Quality Gate passedIssues Measures |
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
SONARPY-2370