blob: 524f02a7a24e5c4782310696a1b3c424c10dca40 [file] [log] [blame]
// Copyright 2024 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package fix
import (
"go/token"
"go/types"
"github.com/dave/dst"
)
func incDecPre(c *cursor) bool {
stmt, ok := c.Node().(*dst.IncDecStmt)
if !ok {
return true
}
x := stmt.X
if pe, ok := x.(*dst.ParenExpr); ok {
x = pe.X
}
if se, ok := x.(*dst.StarExpr); ok {
x = se.X
}
field, ok := c.trackedProtoFieldSelector(x)
if !ok {
return true
}
if !c.isSideEffectFree(field) {
markMissingRewrite(stmt, "inc/dec statement")
return true
}
val := &dst.BinaryExpr{
X: sel2call(c, "Get", cloneSelectorExpr(c, field), nil, *field.Decorations()),
Y: dst.NewIdent("1"),
}
c.setType(val.Y, types.Typ[types.UntypedInt])
c.setType(val, c.typeOf(field))
if stmt.Tok == token.INC {
val.Op = token.ADD
} else {
val.Op = token.SUB
}
// Not handled: decorations from the inner nodes (ParenExpr,
// StarExpr). While those are unlikely to be there, we would ideally not
// lose those. Perhaps we need a more general solution instead of handling
// decorations on a case-by-case basis.
c.Replace(c.expr2stmt(sel2call(c, "Set", field, val, *stmt.Decorations()), field))
return true
}