-
-
Notifications
You must be signed in to change notification settings - Fork 783
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
Better Support for Guard Clauses in ThrowsCount Rule #2876
Conversation
…xpressions, fix throw count scenarios related to guard clauses and add tests, reuse guard clause code for throw count rule
…checking for ELVIS guard clause
Codecov Report
@@ Coverage Diff @@
## master #2876 +/- ##
============================================
- Coverage 80.28% 80.17% -0.12%
Complexity 2417 2417
============================================
Files 421 421
Lines 7359 7358 -1
Branches 1346 1343 -3
============================================
- Hits 5908 5899 -9
- Misses 756 764 +8
Partials 695 695
Continue to review full report at Codecov.
|
} | ||
throw Exception() | ||
} | ||
""" |
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 looks like all test code templates need 4 extra spaces
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.
@arturbosch good catch, I have fixed it.
|
||
throw Exception() | ||
} | ||
""" |
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 it is right
} else { | ||
if (!it.isGuardClause()) { | ||
firstNonGuardFound = true | ||
inline fun <reified T : KtExpression> KtNamedFunction.yieldStatementsSkippingGuardClauses(): Sequence<KtExpression> = |
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.
Should this return T 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.
@arturbosch sorry if it was not clear, but the generic type T
is for the child expression which can be either return
or throw
. These expressions can be of the sub-types KtReturnExpression
or KtThrowExpression
. The generic finds its purpose in the following line of code:
val descendantExpr = this.findDescendantOfType<T>() ?: return false
And on the consumer side the code looks like the following:
// in ReturnCount.kt
yieldStatementsSkippingGuardClauses<KtReturnExpression>()
// in ThrowsCount.kt
yieldStatementsSkippingGuardClauses<KtThrowExpression>()
Whereas the return type of yieldStatementsSkippingGuardClauses
method is a Sequence
of parent statements, which is always of the type KtExpression
.
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.
Thanks for the explanation.
} else { | ||
if (!it.isGuardClause<T>()) { | ||
firstNonGuardFound = true | ||
yield(it) | ||
} | ||
} |
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.
} else { | |
if (!it.isGuardClause<T>()) { | |
firstNonGuardFound = true | |
yield(it) | |
} | |
} | |
} else if (!it.isGuardClause<T>()) { | |
firstNonGuardFound = true | |
yield(it) | |
} |
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.
@schalkms thanks for the suggestion, it has been applied.
} | ||
|
||
fun KtExpression.isElvisOperatorGuardClause(): Boolean { | ||
val elvisExpr = this.parent as? KtBinaryExpression | ||
return elvisExpr?.operationToken == KtTokens.ELVIS | ||
val elvisExpr = this.findDescendantOfType<KtBinaryExpression>() ?: 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.
I'm not sure if I really understand this change. Could you please shed some light into 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.
@schalkms
Earlier isElvisOperatorGuardClause
was being called as an extension for the child return
expression, and now I have modified it to be called as an extension on the parent statement (which contains the return
/ throw
child expression)
Firstly it makes it generic for both return
and throw
expressions, as it is called on the parent. And secondly it sounds more meaningful, as the the parent statement is a guard clause (and not the child).
@arturbosch @schalkms |
@amitdash291 for |
@arturbosch got it, the clarification about coverage issue. |
This PR achieves the following:
GuardClauses
extension functions generic to support bothreturn
andthrow
expressionsThrowsCount
scenarios related to guard clauses and add tests for the sameGuardClauses
code forThrowsCount
rule