Skip to content

Commit

Permalink
add simple 1-stmt level normalization
Browse files Browse the repository at this point in the history
Signed-off-by: Iskander Sharipov <[email protected]>
  • Loading branch information
quasilyte committed Jan 24, 2019
1 parent 2b5cf9d commit a395ed0
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 7 deletions.
4 changes: 4 additions & 0 deletions astnorm.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ type Config struct {
func Expr(cfg *Config, x ast.Expr) ast.Expr {
return newNormalizer(cfg).normalizeExpr(x)
}

func Stmt(cfg *Config, x ast.Stmt) ast.Stmt {
return newNormalizer(cfg).normalizeStmt(x)
}
42 changes: 42 additions & 0 deletions normalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package astnorm

import (
"go/ast"
"go/token"

"github.com/go-toolsmith/astcast"
"github.com/go-toolsmith/astequal"
"github.com/go-toolsmith/typep"
)

Expand Down Expand Up @@ -35,3 +38,42 @@ func (n *normalizer) normalizeExprList(xs []ast.Expr) []ast.Expr {
}
return xs
}

func (n *normalizer) normalizeStmt(x ast.Stmt) ast.Stmt {
switch x := x.(type) {
case *ast.AssignStmt:
return n.normalizeAssignStmt(x)
case *ast.BlockStmt:
return n.normalizeBlockStmt(x)
default:
return x
}
}

func (n *normalizer) normalizeBlockStmt(b *ast.BlockStmt) *ast.BlockStmt {
for i, x := range b.List {
b.List[i] = n.normalizeStmt(x)
}
return b
}

func (n *normalizer) normalizeAssignStmt(assign *ast.AssignStmt) ast.Stmt {
assign = n.normalizeAssignOp(assign)
return assign
}

func (n *normalizer) normalizeAssignOp(assign *ast.AssignStmt) *ast.AssignStmt {
if assign.Tok != token.ASSIGN || len(assign.Lhs) != 1 {
return assign
}
rhs := astcast.ToBinaryExpr(assign.Rhs[0])
if !astequal.Expr(assign.Lhs[0], rhs.X) {
return assign
}
switch rhs.Op {
case token.ADD:
assign.Tok = token.ADD_ASSIGN
assign.Rhs[0] = n.normalizeExpr(rhs.Y)
}
return assign
}
38 changes: 31 additions & 7 deletions normalizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
"golang.org/x/tools/go/packages"
)

func isTestCase(assign *ast.AssignStmt) bool {
return len(assign.Lhs) == 2 &&
len(assign.Rhs) == 2 &&
astcast.ToIdent(assign.Lhs[0]).Name == "_" &&
astcast.ToIdent(assign.Lhs[1]).Name == "_"
}

func TestNormalizeExpr(t *testing.T) {
pkg := loadPackage(t, "./testdata/normalize_expr.go")
funcs := collectFuncDecls(pkg)
Expand All @@ -19,13 +26,7 @@ func TestNormalizeExpr(t *testing.T) {
for _, fn := range funcs {
for _, stmt := range fn.Body.List {
assign, ok := stmt.(*ast.AssignStmt)
if !ok || len(assign.Lhs) != 2 || len(assign.Rhs) != 2 {
continue
}
if astcast.ToIdent(assign.Lhs[0]).Name != "_" {
continue
}
if astcast.ToIdent(assign.Lhs[1]).Name != "_" {
if !ok || !isTestCase(assign) {
continue
}
input := assign.Rhs[0]
Expand All @@ -40,6 +41,29 @@ func TestNormalizeExpr(t *testing.T) {
}
}

func TestNormalizeStmt(t *testing.T) {
pkg := loadPackage(t, "./testdata/normalize_stmt.go")
funcs := collectFuncDecls(pkg)
cfg := &Config{Info: pkg.TypesInfo}

for _, fn := range funcs {
for _, stmt := range fn.Body.List {
assign, ok := stmt.(*ast.AssignStmt)
if !ok || !isTestCase(assign) {
continue
}
input := assign.Rhs[0].(*ast.FuncLit).Body
want := assign.Rhs[1].(*ast.FuncLit).Body
have := Stmt(cfg, input)
if !astequal.Stmt(have, want) {
pos := pkg.Fset.Position(assign.Pos())
t.Errorf("%s:\nhave: %s\nwant: %s",
pos, astfmt.Sprint(have), astfmt.Sprint(want))
}
}
}
}

func collectFuncDecls(pkg *packages.Package) []*ast.FuncDecl {
var funcs []*ast.FuncDecl
for _, f := range pkg.Syntax {
Expand Down
31 changes: 31 additions & 0 deletions testdata/normalize_stmt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package normalize_stmt

func identityTest() {
var x int

_, _ = func() {
x += 1
}, func() {
x += 1
}
}

func assignOpTest() {
var x int

_, _ = func() {
x = x + 1
}, func() {
x += 1
}
}

func combinedTest() {
var x int

_, _ = func() {
x = x + (1)
}, func() {
x += 1
}
}

0 comments on commit a395ed0

Please sign in to comment.