summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mgechev/revive/rule/exported.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mgechev/revive/rule/exported.go')
-rw-r--r--vendor/github.com/mgechev/revive/rule/exported.go272
1 files changed, 0 insertions, 272 deletions
diff --git a/vendor/github.com/mgechev/revive/rule/exported.go b/vendor/github.com/mgechev/revive/rule/exported.go
deleted file mode 100644
index b68f2bacc1..0000000000
--- a/vendor/github.com/mgechev/revive/rule/exported.go
+++ /dev/null
@@ -1,272 +0,0 @@
-package rule
-
-import (
- "fmt"
- "go/ast"
- "go/token"
- "strings"
- "unicode"
- "unicode/utf8"
-
- "github.com/mgechev/revive/lint"
-)
-
-// ExportedRule lints given else constructs.
-type ExportedRule struct{}
-
-// Apply applies the rule to given file.
-func (r *ExportedRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
- var failures []lint.Failure
-
- if isTest(file) {
- return failures
- }
-
- fileAst := file.AST
- walker := lintExported{
- file: file,
- fileAst: fileAst,
- onFailure: func(failure lint.Failure) {
- failures = append(failures, failure)
- },
- genDeclMissingComments: make(map[*ast.GenDecl]bool),
- }
-
- ast.Walk(&walker, fileAst)
-
- return failures
-}
-
-// Name returns the rule name.
-func (r *ExportedRule) Name() string {
- return "exported"
-}
-
-type lintExported struct {
- file *lint.File
- fileAst *ast.File
- lastGen *ast.GenDecl
- genDeclMissingComments map[*ast.GenDecl]bool
- onFailure func(lint.Failure)
-}
-
-func (w *lintExported) lintFuncDoc(fn *ast.FuncDecl) {
- if !ast.IsExported(fn.Name.Name) {
- // func is unexported
- return
- }
- kind := "function"
- name := fn.Name.Name
- if fn.Recv != nil && len(fn.Recv.List) > 0 {
- // method
- kind = "method"
- recv := receiverType(fn)
- if !ast.IsExported(recv) {
- // receiver is unexported
- return
- }
- if commonMethods[name] {
- return
- }
- switch name {
- case "Len", "Less", "Swap":
- if w.file.Pkg.Sortable[recv] {
- return
- }
- }
- name = recv + "." + name
- }
- if fn.Doc == nil {
- w.onFailure(lint.Failure{
- Node: fn,
- Confidence: 1,
- Category: "comments",
- Failure: fmt.Sprintf("exported %s %s should have comment or be unexported", kind, name),
- })
- return
- }
- s := normalizeText(fn.Doc.Text())
- prefix := fn.Name.Name + " "
- if !strings.HasPrefix(s, prefix) {
- w.onFailure(lint.Failure{
- Node: fn.Doc,
- Confidence: 0.8,
- Category: "comments",
- Failure: fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix),
- })
- }
-}
-
-func (w *lintExported) checkStutter(id *ast.Ident, thing string) {
- pkg, name := w.fileAst.Name.Name, id.Name
- if !ast.IsExported(name) {
- // unexported name
- return
- }
- // A name stutters if the package name is a strict prefix
- // and the next character of the name starts a new word.
- if len(name) <= len(pkg) {
- // name is too short to stutter.
- // This permits the name to be the same as the package name.
- return
- }
- if !strings.EqualFold(pkg, name[:len(pkg)]) {
- return
- }
- // We can assume the name is well-formed UTF-8.
- // If the next rune after the package name is uppercase or an underscore
- // the it's starting a new word and thus this name stutters.
- rem := name[len(pkg):]
- if next, _ := utf8.DecodeRuneInString(rem); next == '_' || unicode.IsUpper(next) {
- w.onFailure(lint.Failure{
- Node: id,
- Confidence: 0.8,
- Category: "naming",
- Failure: fmt.Sprintf("%s name will be used as %s.%s by other packages, and that stutters; consider calling this %s", thing, pkg, name, rem),
- })
- }
-}
-
-func (w *lintExported) lintTypeDoc(t *ast.TypeSpec, doc *ast.CommentGroup) {
- if !ast.IsExported(t.Name.Name) {
- return
- }
- if doc == nil {
- w.onFailure(lint.Failure{
- Node: t,
- Confidence: 1,
- Category: "comments",
- Failure: fmt.Sprintf("exported type %v should have comment or be unexported", t.Name),
- })
- return
- }
-
- s := normalizeText(doc.Text())
- articles := [...]string{"A", "An", "The", "This"}
- for _, a := range articles {
- if t.Name.Name == a {
- continue
- }
- if strings.HasPrefix(s, a+" ") {
- s = s[len(a)+1:]
- break
- }
- }
- if !strings.HasPrefix(s, t.Name.Name+" ") {
- w.onFailure(lint.Failure{
- Node: doc,
- Confidence: 1,
- Category: "comments",
- Failure: fmt.Sprintf(`comment on exported type %v should be of the form "%v ..." (with optional leading article)`, t.Name, t.Name),
- })
- }
-}
-
-func (w *lintExported) lintValueSpecDoc(vs *ast.ValueSpec, gd *ast.GenDecl, genDeclMissingComments map[*ast.GenDecl]bool) {
- kind := "var"
- if gd.Tok == token.CONST {
- kind = "const"
- }
-
- if len(vs.Names) > 1 {
- // Check that none are exported except for the first.
- for _, n := range vs.Names[1:] {
- if ast.IsExported(n.Name) {
- w.onFailure(lint.Failure{
- Category: "comments",
- Confidence: 1,
- Failure: fmt.Sprintf("exported %s %s should have its own declaration", kind, n.Name),
- Node: vs,
- })
- return
- }
- }
- }
-
- // Only one name.
- name := vs.Names[0].Name
- if !ast.IsExported(name) {
- return
- }
-
- if vs.Doc == nil && gd.Doc == nil {
- if genDeclMissingComments[gd] {
- return
- }
- block := ""
- if kind == "const" && gd.Lparen.IsValid() {
- block = " (or a comment on this block)"
- }
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: vs,
- Category: "comments",
- Failure: fmt.Sprintf("exported %s %s should have comment%s or be unexported", kind, name, block),
- })
- genDeclMissingComments[gd] = true
- return
- }
- // If this GenDecl has parens and a comment, we don't check its comment form.
- if gd.Lparen.IsValid() && gd.Doc != nil {
- return
- }
- // The relevant text to check will be on either vs.Doc or gd.Doc.
- // Use vs.Doc preferentially.
- doc := vs.Doc
- if doc == nil {
- doc = gd.Doc
- }
- prefix := name + " "
- s := normalizeText(doc.Text())
- if !strings.HasPrefix(s, prefix) {
- w.onFailure(lint.Failure{
- Confidence: 1,
- Node: doc,
- Category: "comments",
- Failure: fmt.Sprintf(`comment on exported %s %s should be of the form "%s..."`, kind, name, prefix),
- })
- }
-}
-
-// normalizeText is a helper function that normalizes comment strings by:
-// * removing one leading space
-//
-// This function is needed because ast.CommentGroup.Text() does not handle //-style and /*-style comments uniformly
-func normalizeText(t string) string {
- return strings.TrimPrefix(t, " ")
-}
-
-func (w *lintExported) Visit(n ast.Node) ast.Visitor {
- switch v := n.(type) {
- case *ast.GenDecl:
- if v.Tok == token.IMPORT {
- return nil
- }
- // token.CONST, token.TYPE or token.VAR
- w.lastGen = v
- return w
- case *ast.FuncDecl:
- w.lintFuncDoc(v)
- if v.Recv == nil {
- // Only check for stutter on functions, not methods.
- // Method names are not used package-qualified.
- w.checkStutter(v.Name, "func")
- }
- // Don't proceed inside funcs.
- return nil
- case *ast.TypeSpec:
- // inside a GenDecl, which usually has the doc
- doc := v.Doc
- if doc == nil {
- doc = w.lastGen.Doc
- }
- w.lintTypeDoc(v, doc)
- w.checkStutter(v.Name, "type")
- // Don't proceed inside types.
- return nil
- case *ast.ValueSpec:
- w.lintValueSpecDoc(v, w.lastGen, w.genDeclMissingComments)
- return nil
- }
- return w
-}