1
0
mirror of https://github.com/mgechev/revive.git synced 2024-11-24 08:32:22 +02:00
revive/rule/utils.go

136 lines
2.6 KiB
Go
Raw Normal View History

2018-01-22 04:04:41 +02:00
package rule
2017-11-27 04:48:07 +02:00
import (
2017-11-27 05:28:18 +02:00
"fmt"
2017-11-27 04:58:15 +02:00
"go/ast"
2017-11-27 06:03:12 +02:00
"go/types"
2017-11-27 05:28:18 +02:00
"regexp"
2017-11-27 04:48:07 +02:00
"strings"
2018-01-22 04:04:41 +02:00
"github.com/mgechev/revive/linter"
2017-11-27 04:48:07 +02:00
)
2017-11-27 04:58:15 +02:00
const styleGuideBase = "https://golang.org/wiki/CodeReviewComments"
// isBlank returns whether id is the blank identifier "_".
// If id == nil, the answer is false.
func isBlank(id *ast.Ident) bool { return id != nil && id.Name == "_" }
2018-01-22 04:04:41 +02:00
func isTest(f *linter.File) bool {
2017-11-27 04:48:07 +02:00
return strings.HasSuffix(f.Name, "_test.go")
}
2017-11-27 05:19:41 +02:00
var commonMethods = map[string]bool{
"Error": true,
"Read": true,
"ServeHTTP": true,
"String": true,
"Write": true,
}
func receiverType(fn *ast.FuncDecl) string {
switch e := fn.Recv.List[0].Type.(type) {
case *ast.Ident:
return e.Name
case *ast.StarExpr:
if id, ok := e.X.(*ast.Ident); ok {
return id.Name
}
}
// The parser accepts much more than just the legal forms.
return "invalid-type"
}
2017-11-27 05:28:18 +02:00
var knownNameExceptions = map[string]bool{
"LastInsertId": true, // must match database/sql
"kWh": true,
}
func isCgoExported(f *ast.FuncDecl) bool {
if f.Recv != nil || f.Doc == nil {
return false
}
cgoExport := regexp.MustCompile(fmt.Sprintf("(?m)^//export %s$", regexp.QuoteMeta(f.Name.Name)))
for _, c := range f.Doc.List {
if cgoExport.MatchString(c.Text) {
return true
}
}
return false
}
var commonInitialisms = map[string]bool{
"ACL": true,
"API": true,
"ASCII": true,
"CPU": true,
"CSS": true,
"DNS": true,
"EOF": true,
"GUID": true,
"HTML": true,
"HTTP": true,
"HTTPS": true,
"ID": true,
"IP": true,
"JSON": true,
"LHS": true,
"QPS": true,
"RAM": true,
"RHS": true,
"RPC": true,
"SLA": true,
"SMTP": true,
"SQL": true,
"SSH": true,
"TCP": true,
"TLS": true,
"TTL": true,
"UDP": true,
"UI": true,
"UID": true,
"UUID": true,
"URI": true,
"URL": true,
"UTF8": true,
"VM": true,
"XML": true,
"XMPP": true,
"XSRF": true,
"XSS": true,
}
var allCapsRE = regexp.MustCompile(`^[A-Z0-9_]+$`)
2017-11-27 06:03:12 +02:00
func isIdent(expr ast.Expr, ident string) bool {
id, ok := expr.(*ast.Ident)
return ok && id.Name == ident
}
var zeroLiteral = map[string]bool{
"false": true, // bool
// runes
`'\x00'`: true,
`'\000'`: true,
// strings
`""`: true,
"``": true,
// numerics
"0": true,
"0.": true,
"0.0": true,
"0i": true,
}
func validType(T types.Type) bool {
return T != nil &&
T != types.Typ[types.Invalid] &&
!strings.Contains(T.String(), "invalid type") // good but not foolproof
}
2017-11-27 06:14:25 +02:00
func isPkgDot(expr ast.Expr, pkg, name string) bool {
sel, ok := expr.(*ast.SelectorExpr)
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
}