Suggest replacing "x += 1" with "x++", and "y -= 1" with "y--".
This is a common mistake/oversight that ex-Python programmers make.
diff --git a/lint.go b/lint.go
index 31fb872..41b4fa2 100644
--- a/lint.go
+++ b/lint.go
@@ -77,6 +77,7 @@
f.lintErrors()
f.lintErrorStrings()
f.lintReceiverNames()
+ f.lintIncDec()
return f.problems
}
@@ -836,6 +837,34 @@
})
}
+// lintIncDec examines statements that increment or decrement a variable.
+// It complains if they don't use x++ or x--.
+func (f *file) lintIncDec() {
+ f.walk(func(n ast.Node) bool {
+ as, ok := n.(*ast.AssignStmt)
+ if !ok {
+ return true
+ }
+ if len(as.Lhs) != 1 {
+ return true
+ }
+ if !isOne(as.Rhs[0]) {
+ return true
+ }
+ var suffix string
+ switch as.Tok {
+ case token.ADD_ASSIGN:
+ suffix = "++"
+ case token.SUB_ASSIGN:
+ suffix = "--"
+ default:
+ return true
+ }
+ f.errorf(as, 0.8, "should replace %s with %s%s", f.render(as), f.render(as.Lhs[0]), suffix)
+ return true
+ })
+}
+
func receiverType(fn *ast.FuncDecl) string {
switch e := fn.Recv.List[0].Type.(type) {
case *ast.Ident:
@@ -891,6 +920,11 @@
return ok && isIdent(sel.X, pkg) && isIdent(sel.Sel, name)
}
+func isOne(expr ast.Expr) bool {
+ lit, ok := expr.(*ast.BasicLit)
+ return ok && lit.Kind == token.INT && lit.Value == "1"
+}
+
func isIntLiteral(expr ast.Expr) bool {
// Either a BasicLit with Kind token.INT,
// or some combination of a UnaryExpr with Op token.SUB (for "-<lit>")
diff --git a/testdata/inc.go b/testdata/inc.go
new file mode 100644
index 0000000..3868bee
--- /dev/null
+++ b/testdata/inc.go
@@ -0,0 +1,14 @@
+// Test for use of x++ and x--.
+
+// Package pkg ...
+package pkg
+
+func addOne(x int) int {
+ x += 1 // MATCH /x\+\+/
+ return x
+}
+
+func subOneInLoop(y int) {
+ for ; y > 0; y -= 1 { // MATCH /y--/
+ }
+}