-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
refactor: use a more straightforward return value #9519
base: master
Are you sure you want to change the base?
Conversation
Important Review skippedAuto reviews are limited to specific labels. 🏷️ Labels to auto review (1)
Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Thanks for the changes. Looks like you're detecting this in other repos as well, so my question here: Did you find these using a script? If yes, are these the only occurrences in this repo? |
Yes, this is a detection program I use, but my logic may have some problems, and there will be a lot of false positives at present. Please wait for me to optimize the code and do more accurate positioning func checkFuncForRedundantReturn(fset *token.FileSet, funcDecl *ast.FuncDecl, path string) {
if funcDecl.Body == nil {
return
}
var lastIfStmt *ast.IfStmt
var lastReturnStmt *ast.ReturnStmt
var errReassigned bool = false
// 首先找到最后一个 return 语句
ast.Inspect(funcDecl.Body, func(n ast.Node) bool {
switch node := n.(type) {
case *ast.IfStmt:
if isErrorCheck(node.Cond) {
lastIfStmt = node
}
case *ast.AssignStmt:
// 检查是否有对 err 的重新赋值
for _, lhs := range node.Lhs {
if ident, ok := lhs.(*ast.Ident); ok {
if ident.Name == "err" {
// 找到了对 err 的重新赋值,并且这个赋值发生在最后一个错误检查之后
if lastIfStmt != nil && node.Pos() > lastIfStmt.Pos() {
errReassigned = true
}
}
}
}
case *ast.ReturnStmt:
lastReturnStmt = node
}
return true
})
// 如果最后一个 return 包含 err 且在 if err != nil 之后,并且没有对 err 重新赋值
if lastReturnStmt != nil && lastIfStmt != nil {
if !isInsideIfBlock(lastReturnStmt, lastIfStmt) &&
containsErrorIdent(lastReturnStmt) &&
!errReassigned { // 添加这个条件
// 检查这个 return 是否是函数的最后一个语句
if isLastStatement(funcDecl.Body, lastReturnStmt) {
pos := fset.Position(lastReturnStmt.Pos())
fmt.Printf("%s:%d: 发现函数末尾冗余的错误返回语句\n", path, pos.Line)
}
}
}
}
// 检查是否是 err != nil 的条件
func isErrorCheck(expr ast.Expr) bool {
if binaryExpr, ok := expr.(*ast.BinaryExpr); ok {
if binaryExpr.Op == token.NEQ {
if ident, ok := binaryExpr.X.(*ast.Ident); ok {
if ident.Name == "err" || ident.Name == "e" {
if nilLit, ok := binaryExpr.Y.(*ast.Ident); ok {
return nilLit.Name == "nil"
}
}
}
}
}
return false
}
// 检查返回语句是否在 if 块内
func isInsideIfBlock(returnStmt *ast.ReturnStmt, ifStmt *ast.IfStmt) bool {
start := ifStmt.Body.Pos()
end := ifStmt.Body.End()
return returnStmt.Pos() >= start && returnStmt.Pos() <= end
}
// 检查返回语句是否包含 err 标识符
func containsErrorIdent(returnStmt *ast.ReturnStmt) bool {
for _, result := range returnStmt.Results {
if ident, ok := result.(*ast.Ident); ok {
if ident.Name == "err" || ident.Name == "e" {
return true
}
}
}
return false
}
// 检查语句是否是函数体的最后一个语句
func isLastStatement(body *ast.BlockStmt, stmt ast.Stmt) bool {
if len(body.List) == 0 {
return false
}
return body.List[len(body.List)-1] == stmt
} |
The false postive like this: // GetClientSession loads the ClientSession with the given ID from the DB.
func (c *ClientDB) GetClientSession(id SessionID,
opts ...ClientSessionListOption) (*ClientSession, error) {
var sess *ClientSession
err := kvdb.View(c.db, func(tx kvdb.RTx) error {
sessionsBkt := tx.ReadBucket(cSessionBkt)
if sessionsBkt == nil {
return ErrUninitializedDB
}
chanIDIndexBkt := tx.ReadBucket(cChanIDIndexBkt)
if chanIDIndexBkt == nil {
return ErrUninitializedDB
}
session, err := c.getClientSession(
sessionsBkt, chanIDIndexBkt, id[:], opts...,
)
if err != nil {
return err
}
sess = session
return nil
}, func() {})
return sess, err
} |
Thanks for your patience. @Reallyfe @guggero I have found more cases like this, and I believe there won't be any more such cases. |
Signed-off-by: fuyangpengqi <[email protected]>
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 finding these!
Luckily none of these occurrences produced any incorrect results. But definitely nice to have them fixed.
LGTM pending linter fix.
@@ -561,7 +561,7 @@ func getOutgoingBalance(node route.Vertex, outgoingChans map[uint64]struct{}, | |||
if err != nil { | |||
return 0, 0, err | |||
} | |||
return max, total, err | |||
return max, total, nil |
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.
Linter wants a newline before this return
.
Change Description
use a more straightforward return value
Steps to Test
Steps for reviewers to follow to test the change.
Pull Request Checklist
Testing
Code Style and Documentation
[skip ci]
in the commit message for small changes.📝 Please see our Contribution Guidelines for further guidance.