Skip to content

Commit

Permalink
adds rule use-any (#660)
Browse files Browse the repository at this point in the history
  • Loading branch information
chavacava authored Mar 29, 2022
1 parent 318db94 commit 671c55d
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ List of all available rules. The rules ported from `golint` are left unchanged a
| [`useless-break`](./RULES_DESCRIPTIONS.md#useless-break) | n/a | Warns on useless `break` statements in case clauses | no | no |
| [`banned-characters`](./RULES_DESCRIPTIONS.md#banned-characters) | n/a | Checks banned characters in identifiers | no | no |
| [`optimize-operands-order`](./RULES_DESCRIPTIONS.md#optimize-operands-order) | n/a | Checks inefficient conditional expressions | no | no |
| [`use-any`](./RULES_DESCRIPTIONS.md#use-any) | n/a | Proposes to replace `interface{}` with its alias `any` | no | no |

## Configurable rules

Expand Down
7 changes: 7 additions & 0 deletions RULES_DESCRIPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ List of all available rules.
- [unreachable-code](#unreachable-code)
- [unused-parameter](#unused-parameter)
- [unused-receiver](#unused-receiver)
- [use-any](#use-any)
- [useless-break](#useless-break)
- [waitgroup-by-value](#waitgroup-by-value)

Expand Down Expand Up @@ -670,6 +671,12 @@ _Description_: This rule warns on unused method receivers. Methods with unused r

_Configuration_: N/A

## use-any

_Description_: Since GO 1.18, `interface{}` has an alias: `any`. This rule proposes to replace instances of `interface{}` with `any`.

_Configuration_: N/A

## useless-break

_Description_: This rule warns on useless `break` statements in case clauses of switch and select statements. GO, unlike other programming languages like C, only executes statements of the selected case while ignoring the subsequent case clauses.
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ var allRules = append([]lint.Rule{
&rule.TimeEqualRule{},
&rule.BannedCharsRule{},
&rule.OptimizeOperandsOrderRule{},
&rule.UseAnyRule{},
}, defaultRules...)

var allFormatters = []lint.Formatter{
Expand Down
54 changes: 54 additions & 0 deletions rule/use-any.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package rule

import (
"go/ast"

"github.com/mgechev/revive/lint"
)

// UseAnyRule lints given else constructs.
type UseAnyRule struct{}

// Apply applies the rule to given file.
func (r *UseAnyRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
var failures []lint.Failure

walker := lintUseAny{
onFailure: func(failure lint.Failure) {
failures = append(failures, failure)
},
}
fileAst := file.AST
ast.Walk(walker, fileAst)

return failures
}

// Name returns the rule name.
func (r *UseAnyRule) Name() string {
return "use-any"
}

type lintUseAny struct {
onFailure func(lint.Failure)
}

func (w lintUseAny) Visit(n ast.Node) ast.Visitor {
it, ok := n.(*ast.InterfaceType)
if !ok {
return w
}

if len(it.Methods.List) != 0 {
return w // it is not and empty interface
}

w.onFailure(lint.Failure{
Node: n,
Confidence: 1,
Category: "naming",
Failure: "since GO 1.18 'interface{}' can be replaced by 'any'",
})

return w
}
11 changes: 11 additions & 0 deletions test/use-any_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package test

import (
"testing"

"github.com/mgechev/revive/rule"
)

func TestUseAny(t *testing.T) {
testRule(t, "use-any", &rule.UseAnyRule{})
}
31 changes: 31 additions & 0 deletions testdata/use-any.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package pkg

var i interface{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/

type t interface{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
type a = interface{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/

func any1(a interface{}) { // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
m1 := map[interface{}]string{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
m2 := map[int]interface{}{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
a := []interface{}{} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
m3 := make(map[int]interface{}, 1) // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
a2 := make([]interface{}, 2) // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/
}

func any2(a int) interface{} {} // MATCH /since GO 1.18 'interface{}' can be replaced by 'any'/

var ni interface{ Close() }

type nt interface{ Close() }
type na = interface{ Close() }

func nany1(a interface{ Close() }) {
nm1 := map[interface{ Close() }]string{}
nm2 := map[int]interface{ Close() }{}
na := []interface{ Close() }{}
nm3 := make(map[int]interface{ Close() }, 1)
na2 := make([]interface{ Close() }, 2)
}

func nany2(a int) interface{ Close() } {}

0 comments on commit 671c55d

Please sign in to comment.