1package filter
2
3import (
4	"go/ast"
5	"go/constant"
6	"go/token"
7	"go/types"
8)
9
10func IncDecStmt(stmt ast.Stmt, info *types.Info) ast.Stmt {
11	if s, ok := stmt.(*ast.IncDecStmt); ok {
12		t := info.TypeOf(s.X)
13		if iExpr, isIExpr := s.X.(*ast.IndexExpr); isIExpr {
14			switch u := info.TypeOf(iExpr.X).Underlying().(type) {
15			case *types.Array:
16				t = u.Elem()
17			case *types.Slice:
18				t = u.Elem()
19			case *types.Map:
20				t = u.Elem()
21			}
22		}
23
24		tok := token.ADD_ASSIGN
25		if s.Tok == token.DEC {
26			tok = token.SUB_ASSIGN
27		}
28
29		one := &ast.BasicLit{Kind: token.INT}
30		info.Types[one] = types.TypeAndValue{Type: t, Value: constant.MakeInt64(1)}
31
32		return &ast.AssignStmt{
33			Lhs: []ast.Expr{s.X},
34			Tok: tok,
35			Rhs: []ast.Expr{one},
36		}
37	}
38	return stmt
39}
40