mirror of
https://github.com/reactos/syzkaller.git
synced 2024-11-23 03:19:51 +00:00
tools/syz-linter: check comments format
Check for capitalization, dots at the end and two spaces after a period. Update #1876
This commit is contained in:
parent
c1147c8df7
commit
115e19300f
@ -61,14 +61,13 @@ var SyzAnalyzer = &analysis.Analyzer{
|
||||
func run(p *analysis.Pass) (interface{}, error) {
|
||||
pass := (*Pass)(p)
|
||||
for _, file := range pass.Files {
|
||||
stmts := make(map[int]bool)
|
||||
ast.Inspect(file, func(n ast.Node) bool {
|
||||
if n == nil {
|
||||
return true
|
||||
}
|
||||
stmts[pass.Fset.Position(n.Pos()).Line] = true
|
||||
switch n := n.(type) {
|
||||
case *ast.File:
|
||||
for _, group := range n.Comments {
|
||||
for _, comment := range group.List {
|
||||
pass.checkComment(comment)
|
||||
}
|
||||
}
|
||||
case *ast.BinaryExpr:
|
||||
pass.checkStringLenCompare(n)
|
||||
case *ast.FuncType:
|
||||
@ -80,6 +79,11 @@ func run(p *analysis.Pass) (interface{}, error) {
|
||||
}
|
||||
return true
|
||||
})
|
||||
for _, group := range file.Comments {
|
||||
for _, comment := range group.List {
|
||||
pass.checkComment(comment, stmts, len(group.List) == 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
@ -98,22 +102,50 @@ func (pass *Pass) typ(e ast.Expr) types.Type {
|
||||
}
|
||||
|
||||
// checkComment warns about C++-style multiline comments (we don't use them in the codebase)
|
||||
// and about "//nospace", "// tabs and spaces" and similar.
|
||||
func (pass *Pass) checkComment(n *ast.Comment) {
|
||||
// and about "//nospace", "// tabs and spaces", two spaces after a period, etc.
|
||||
// See the following sources for some justification:
|
||||
// https://pep8.org/#comments
|
||||
// https://nedbatchelder.com/blog/201401/comments_should_be_sentences.html
|
||||
// https://www.cultofpedagogy.com/two-spaces-after-period
|
||||
func (pass *Pass) checkComment(n *ast.Comment, stmts map[int]bool, oneline bool) {
|
||||
if strings.HasPrefix(n.Text, "/*") {
|
||||
pass.report(n, "Use C-style comments // instead of /* */")
|
||||
return
|
||||
}
|
||||
if allowedComments.MatchString(n.Text) {
|
||||
if specialComment.MatchString(n.Text) {
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(n.Text, "//go:generate") {
|
||||
if !allowedComments.MatchString(n.Text) {
|
||||
pass.report(n, "Use either //<one-or-more-spaces>comment or //<one-or-more-tabs>comment format for comments")
|
||||
return
|
||||
}
|
||||
if strings.Contains(n.Text, ". ") {
|
||||
pass.report(n, "Use one space after a period")
|
||||
return
|
||||
}
|
||||
if !oneline || onelineExceptions.MatchString(n.Text) {
|
||||
return
|
||||
}
|
||||
// The following checks are only done for one-line comments,
|
||||
// because multi-line comment blocks are harder to understand.
|
||||
standalone := !stmts[pass.Fset.Position(n.Pos()).Line]
|
||||
if standalone && lowerCaseComment.MatchString(n.Text) {
|
||||
pass.report(n, "Standalone comments should be complete sentences"+
|
||||
" with first word capitalized and a period at the end")
|
||||
}
|
||||
if noPeriodComment.MatchString(n.Text) {
|
||||
pass.report(n, "Add a period at the end of the comment")
|
||||
return
|
||||
}
|
||||
pass.report(n, "Use either //<one-or-more-spaces>comment or //<one-or-more-tabs>comment format for comments")
|
||||
}
|
||||
|
||||
var allowedComments = regexp.MustCompile(`^//($| +[^ ]| +[^ ])`)
|
||||
var (
|
||||
allowedComments = regexp.MustCompile(`^//($| +[^ ]| +[^ ])`)
|
||||
noPeriodComment = regexp.MustCompile(`^// [A-Z][a-z].+[a-z]$`)
|
||||
lowerCaseComment = regexp.MustCompile(`^// [a-z]+ `)
|
||||
onelineExceptions = regexp.MustCompile(`// want \"|http:|https:`)
|
||||
specialComment = regexp.MustCompile(`//go:generate|// nolint:`)
|
||||
)
|
||||
|
||||
// checkStringLenCompare checks for string len comparisons with 0.
|
||||
// E.g.: if len(str) == 0 {} should be if str == "" {}.
|
||||
@ -188,7 +220,7 @@ func (pass *Pass) reportFuncArgs(fields []*ast.Field, first, last int) {
|
||||
pass.report(fields[first], "Use '%v %v'", names[2:], fields[first].Type)
|
||||
}
|
||||
|
||||
// checkLogErrorFormat warns about log/error messages starting with capital letter or ending with dot.
|
||||
// checkLogErrorFormat warns about log/error messages starting with capital letter or ending with a period.
|
||||
func (pass *Pass) checkLogErrorFormat(n *ast.CallExpr) {
|
||||
fun, ok := n.Fun.(*ast.SelectorExpr)
|
||||
if !ok {
|
||||
@ -217,7 +249,7 @@ func (pass *Pass) checkLogErrorFormat(n *ast.CallExpr) {
|
||||
return
|
||||
}
|
||||
if val[ln-1] == '.' && (ln < 3 || val[ln-2] != '.' || val[ln-3] != '.') {
|
||||
pass.report(lit, "Don't use dot at the end of log/error messages")
|
||||
pass.report(lit, "Don't use period at the end of log/error messages")
|
||||
}
|
||||
if val[ln-1] == '\n' {
|
||||
pass.report(lit, "Don't use \\n at the end of log/error messages")
|
||||
|
@ -32,7 +32,10 @@ func returnString() string { return "foo" }
|
||||
// Tab and spaces. // want "Use either //<one-or-more-spaces>comment or //<one-or-more-tabs>comment format for comments"
|
||||
// Space and tab. // want "Use either //<one-or-more-spaces>comment or //<one-or-more-tabs>comment format for comments"
|
||||
func checkCommentSpace() {
|
||||
// Comment without a dot at the end
|
||||
checkCommentSpace() // lower-case comment is OK
|
||||
// Capital letter comment.
|
||||
checkCommentSpace()
|
||||
// Don't use 2 spaces after dot. Like this. // want "Use one space after a period"
|
||||
checkCommentSpace()
|
||||
}
|
||||
|
||||
@ -46,7 +49,7 @@ func funcArgsBad0(a int, b int) { // want "Use 'a, b int'"
|
||||
}
|
||||
|
||||
func funcArgsBad1() (a int, b int) { // want "Use 'a, b int'"
|
||||
return 0, 0
|
||||
return 0, 0 // lower-case comment is OK
|
||||
}
|
||||
|
||||
func funcArgsBad2(a int16, b, c uint32, d uint32, e int16) { // want "Use 'b, c, d uint32'"
|
||||
@ -66,7 +69,7 @@ func logErrorMessages() {
|
||||
log.Fatalf("Bad message %v", 1) // want "Don't start log/error messages with a Capital letter"
|
||||
log.Printf("Bad message %v", 1) // want "Don't start log/error messages with a Capital letter"
|
||||
log.Print("Bad message") // want "Don't start log/error messages with a Capital letter"
|
||||
log.Print("also ad message.") // want "Don't use dot at the end of log/error messages"
|
||||
log.Print("also ad message.") // want "Don't use period at the end of log/error messages"
|
||||
log.Print("no new lines\n") // want "Don't use \\\\n at the end of log/error messages"
|
||||
log.Print("") // want "Don't use empty log/error messages"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user