mirror of
https://github.com/mgechev/revive.git
synced 2025-11-23 22:04:49 +02:00
* Refactoring on atomic rule: -Main modification: move func gofmt to utils.go * Refactoring on constant-logical-expr rule Simplifies equality check of subexpressions by using gofmt function
This commit is contained in:
@@ -1,10 +1,7 @@
|
|||||||
package rule
|
package rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/printer"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
|
|
||||||
@@ -18,7 +15,7 @@ type AtomicRule struct{}
|
|||||||
func (r *AtomicRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
func (r *AtomicRule) Apply(file *lint.File, _ lint.Arguments) []lint.Failure {
|
||||||
var failures []lint.Failure
|
var failures []lint.Failure
|
||||||
walker := atomic{
|
walker := atomic{
|
||||||
file: file,
|
pkgTypesInfo: file.Pkg.TypesInfo,
|
||||||
onFailure: func(failure lint.Failure) {
|
onFailure: func(failure lint.Failure) {
|
||||||
failures = append(failures, failure)
|
failures = append(failures, failure)
|
||||||
},
|
},
|
||||||
@@ -35,8 +32,8 @@ func (r *AtomicRule) Name() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type atomic struct {
|
type atomic struct {
|
||||||
file *lint.File
|
pkgTypesInfo *types.Info
|
||||||
onFailure func(lint.Failure)
|
onFailure func(lint.Failure)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w atomic) Visit(node ast.Node) ast.Visitor {
|
func (w atomic) Visit(node ast.Node) ast.Visitor {
|
||||||
@@ -46,10 +43,10 @@ func (w atomic) Visit(node ast.Node) ast.Visitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(n.Lhs) != len(n.Rhs) {
|
if len(n.Lhs) != len(n.Rhs) {
|
||||||
return w
|
return nil // skip assignment sub-tree
|
||||||
}
|
}
|
||||||
if len(n.Lhs) == 1 && n.Tok == token.DEFINE {
|
if len(n.Lhs) == 1 && n.Tok == token.DEFINE {
|
||||||
return w
|
return nil // skip assignment sub-tree
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, right := range n.Rhs {
|
for i, right := range n.Rhs {
|
||||||
@@ -62,8 +59,8 @@ func (w atomic) Visit(node ast.Node) ast.Visitor {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pkgIdent, _ := sel.X.(*ast.Ident)
|
pkgIdent, _ := sel.X.(*ast.Ident)
|
||||||
if w.file.Pkg.TypesInfo != nil {
|
if w.pkgTypesInfo != nil {
|
||||||
pkgName, ok := w.file.Pkg.TypesInfo.Uses[pkgIdent].(*types.PkgName)
|
pkgName, ok := w.pkgTypesInfo.Uses[pkgIdent].(*types.PkgName)
|
||||||
if !ok || pkgName.Imported().Path() != "sync/atomic" {
|
if !ok || pkgName.Imported().Path() != "sync/atomic" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -79,15 +76,15 @@ func (w atomic) Visit(node ast.Node) ast.Visitor {
|
|||||||
broken := false
|
broken := false
|
||||||
|
|
||||||
if uarg, ok := arg.(*ast.UnaryExpr); ok && uarg.Op == token.AND {
|
if uarg, ok := arg.(*ast.UnaryExpr); ok && uarg.Op == token.AND {
|
||||||
broken = w.gofmt(left) == w.gofmt(uarg.X)
|
broken = gofmt(left) == gofmt(uarg.X)
|
||||||
} else if star, ok := left.(*ast.StarExpr); ok {
|
} else if star, ok := left.(*ast.StarExpr); ok {
|
||||||
broken = w.gofmt(star.X) == w.gofmt(arg)
|
broken = gofmt(star.X) == gofmt(arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if broken {
|
if broken {
|
||||||
w.onFailure(lint.Failure{
|
w.onFailure(lint.Failure{
|
||||||
Confidence: 1,
|
Confidence: 1,
|
||||||
Failure: fmt.Sprintf("direct assignment to atomic value"),
|
Failure: "direct assignment to atomic value",
|
||||||
Node: n,
|
Node: n,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -95,11 +92,3 @@ func (w atomic) Visit(node ast.Node) ast.Visitor {
|
|||||||
}
|
}
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
// gofmt returns a string representation of the expression.
|
|
||||||
func (w atomic) gofmt(x ast.Expr) string {
|
|
||||||
buf := bytes.Buffer{}
|
|
||||||
fs := token.NewFileSet()
|
|
||||||
printer.Fprint(&buf, fs, x)
|
|
||||||
return buf.String()
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
package rule
|
package rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"github.com/mgechev/revive/lint"
|
"github.com/mgechev/revive/lint"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/format"
|
|
||||||
"go/token"
|
"go/token"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -43,7 +40,7 @@ func (w *lintConstantLogicalExpr) Visit(node ast.Node) ast.Visitor {
|
|||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
if !w.areEqual(n.X, n.Y) {
|
if gofmt(n.X) != gofmt(n.Y) { // check if subexpressions are the same
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,21 +78,6 @@ func (w *lintConstantLogicalExpr) isInequalityOperator(t token.Token) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w lintConstantLogicalExpr) areEqual(x, y ast.Expr) bool {
|
|
||||||
fset := token.NewFileSet()
|
|
||||||
var buf1 bytes.Buffer
|
|
||||||
if err := format.Node(&buf1, fset, x); err != nil {
|
|
||||||
return false // keep going in case of error
|
|
||||||
}
|
|
||||||
|
|
||||||
var buf2 bytes.Buffer
|
|
||||||
if err := format.Node(&buf2, fset, y); err != nil {
|
|
||||||
return false // keep going in case of error
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("%s", buf1.Bytes()) == fmt.Sprintf("%s", buf2.Bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w lintConstantLogicalExpr) newFailure(node ast.Node, msg string) {
|
func (w lintConstantLogicalExpr) newFailure(node ast.Node, msg string) {
|
||||||
w.onFailure(lint.Failure{
|
w.onFailure(lint.Failure{
|
||||||
Confidence: 1,
|
Confidence: 1,
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package rule
|
package rule
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
|
"go/printer"
|
||||||
"go/token"
|
"go/token"
|
||||||
"go/types"
|
"go/types"
|
||||||
"regexp"
|
"regexp"
|
||||||
@@ -179,3 +181,11 @@ func isExprABooleanLit(n ast.Node) (lexeme string, ok bool) {
|
|||||||
|
|
||||||
return oper.Name, (oper.Name == trueName || oper.Name == falseName)
|
return oper.Name, (oper.Name == trueName || oper.Name == falseName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// gofmt returns a string representation of the expression.
|
||||||
|
func gofmt(x ast.Expr) string {
|
||||||
|
buf := bytes.Buffer{}
|
||||||
|
fs := token.NewFileSet()
|
||||||
|
printer.Fprint(&buf, fs, x)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user