mirror of
https://github.com/mgechev/revive.git
synced 2025-01-10 03:17:11 +02:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
ca1b61fcaa
@ -317,9 +317,9 @@ Currently, type checking is enabled by default. If you want to run the linter wi
|
|||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
|
|
||||||
| [<img alt="mgechev" src="https://avatars1.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) | [<img alt="paul-at-start" src="https://avatars2.githubusercontent.com/u/5486775?v=4&s=117" width="117">](https://github.com/paul-at-start) | [<img alt="chavacava" src="https://avatars2.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) |
|
| [<img alt="mgechev" src="https://avatars1.githubusercontent.com/u/455023?v=4&s=117" width="117">](https://github.com/mgechev) | [<img alt="chavacava" src="https://avatars2.githubusercontent.com/u/25788468?v=4&s=117" width="117">](https://github.com/chavacava) | [<img alt="paul-at-start" src="https://avatars2.githubusercontent.com/u/5486775?v=4&s=117" width="117">](https://github.com/paul-at-start) |
|
||||||
| :---------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: |
|
| :---------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------: |
|
||||||
| [mgechev](https://github.com/mgechev) | [paul-at-start](https://github.com/paul-at-start) | [chavacava](https://github.com/chavacava) |
|
| [mgechev](https://github.com/mgechev) | [chavacava](https://github.com/chavacava) | [paul-at-start](https://github.com/paul-at-start) |
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -2,14 +2,19 @@
|
|||||||
|
|
||||||
package fixtures
|
package fixtures
|
||||||
|
|
||||||
func f(x int) bool { // MATCH /this block is empty, you can remove it/
|
func f(x int) bool {} // Must not match
|
||||||
|
|
||||||
}
|
type foo struct {}
|
||||||
|
|
||||||
|
func (f foo) f(x *int) string {} // Must not match
|
||||||
|
func (f *foo) g(y *int) string {} // Must not match
|
||||||
|
|
||||||
func g(f func() bool) string {
|
func g(f func() bool) string {
|
||||||
{ // MATCH /this block is empty, you can remove it/
|
{ // MATCH /this block is empty, you can remove it/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a := func(e error){} // Must not match
|
||||||
|
|
||||||
if ok := f(); ok { // MATCH /this block is empty, you can remove it/
|
if ok := f(); ok { // MATCH /this block is empty, you can remove it/
|
||||||
// only a comment
|
// only a comment
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,14 +12,20 @@ func Exported() hidden { // MATCH /exported func Exported returns unexported typ
|
|||||||
|
|
||||||
// ExpErr returns a builtin type.
|
// ExpErr returns a builtin type.
|
||||||
func ExpErr() error { // ok
|
func ExpErr() error { // ok
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (hidden) ExpOnHidden() hidden { // ok
|
func (h hidden) ExpOnHidden() hidden { // ok
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (hidden) ForInterface() error {
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface is exported.
|
// Interface is exported.
|
||||||
type Interface interface {
|
type Interface interface {
|
||||||
ExpOnHidden()
|
ForInterface() error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportedAsInterface returns a hidden type as an exported interface, which is fine.
|
// ExportedAsInterface returns a hidden type as an exported interface, which is fine.
|
||||||
|
@ -17,7 +17,7 @@ func (r *EmptyBlockRule) Apply(file *lint.File, arguments lint.Arguments) []lint
|
|||||||
failures = append(failures, failure)
|
failures = append(failures, failure)
|
||||||
}
|
}
|
||||||
|
|
||||||
w := lintEmptyBlock{make(map[*ast.IfStmt]bool), onFailure}
|
w := lintEmptyBlock{make([]*ast.BlockStmt, 0), onFailure}
|
||||||
ast.Walk(w, file.AST)
|
ast.Walk(w, file.AST)
|
||||||
return failures
|
return failures
|
||||||
}
|
}
|
||||||
@ -28,16 +28,32 @@ func (r *EmptyBlockRule) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type lintEmptyBlock struct {
|
type lintEmptyBlock struct {
|
||||||
ignore map[*ast.IfStmt]bool
|
ignore []*ast.BlockStmt
|
||||||
onFailure func(lint.Failure)
|
onFailure func(lint.Failure)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
|
func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
|
||||||
|
fd, ok := node.(*ast.FuncDecl)
|
||||||
|
if ok {
|
||||||
|
w.ignore = append(w.ignore, fd.Body)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
|
fl, ok := node.(*ast.FuncLit)
|
||||||
|
if ok {
|
||||||
|
w.ignore = append(w.ignore, fl.Body)
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
block, ok := node.(*ast.BlockStmt)
|
block, ok := node.(*ast.BlockStmt)
|
||||||
if !ok {
|
if !ok {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if mustIgnore(block, w.ignore) {
|
||||||
|
return w
|
||||||
|
}
|
||||||
|
|
||||||
if len(block.List) == 0 {
|
if len(block.List) == 0 {
|
||||||
w.onFailure(lint.Failure{
|
w.onFailure(lint.Failure{
|
||||||
Confidence: 1,
|
Confidence: 1,
|
||||||
@ -50,3 +66,12 @@ func (w lintEmptyBlock) Visit(node ast.Node) ast.Visitor {
|
|||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mustIgnore(block *ast.BlockStmt, blackList []*ast.BlockStmt) bool {
|
||||||
|
for _, b := range blackList {
|
||||||
|
if b == block {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
@ -84,8 +84,16 @@ func (w lintUnexportedReturn) Visit(n ast.Node) ast.Visitor {
|
|||||||
func exportedType(typ types.Type) bool {
|
func exportedType(typ types.Type) bool {
|
||||||
switch T := typ.(type) {
|
switch T := typ.(type) {
|
||||||
case *types.Named:
|
case *types.Named:
|
||||||
|
obj := T.Obj()
|
||||||
|
switch {
|
||||||
// Builtin types have no package.
|
// Builtin types have no package.
|
||||||
return T.Obj().Pkg() == nil || T.Obj().Exported()
|
case obj.Pkg() == nil:
|
||||||
|
case obj.Exported():
|
||||||
|
default:
|
||||||
|
_, ok := T.Underlying().(*types.Interface)
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
return true
|
||||||
case *types.Map:
|
case *types.Map:
|
||||||
return exportedType(T.Key()) && exportedType(T.Elem())
|
return exportedType(T.Key()) && exportedType(T.Elem())
|
||||||
case interface {
|
case interface {
|
||||||
|
@ -7,9 +7,8 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/mgechev/revive/rule"
|
|
||||||
|
|
||||||
"github.com/mgechev/revive/lint"
|
"github.com/mgechev/revive/lint"
|
||||||
|
"github.com/mgechev/revive/rule"
|
||||||
)
|
)
|
||||||
|
|
||||||
var lintMatch = flag.String("lint.match", "", "restrict fixtures matches to this pattern")
|
var lintMatch = flag.String("lint.match", "", "restrict fixtures matches to this pattern")
|
||||||
@ -55,16 +54,15 @@ func TestAll(t *testing.T) {
|
|||||||
if !rx.MatchString(fi.Name()) {
|
if !rx.MatchString(fi.Name()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
//t.Logf("Testing %s", fi.Name())
|
t.Run(fi.Name(), func(t *testing.T) {
|
||||||
src, err := ioutil.ReadFile(path.Join(baseDir, fi.Name()))
|
src, err := ioutil.ReadFile(path.Join(baseDir, fi.Name()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
|
t.Fatalf("Failed reading %s: %v", fi.Name(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = assertFailures(t, baseDir, fi, src, rules, map[string]lint.RuleConfig{})
|
if err := assertFailures(t, baseDir, fi, src, rules, map[string]lint.RuleConfig{}); err != nil {
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Linting %s: %v", fi.Name(), err)
|
t.Errorf("Linting %s: %v", fi.Name(), err)
|
||||||
continue
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user