Skip to content

Commit

Permalink
syntax: use generics to walk nilable node fields
Browse files Browse the repository at this point in the history
  • Loading branch information
mvdan committed Dec 22, 2024
1 parent 08337a4 commit aa946ad
Showing 1 changed file with 30 additions and 53 deletions.
83 changes: 30 additions & 53 deletions syntax/walk.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,14 @@ func Walk(node Node, f func(Node) bool) {
}
walkList(node.Redirs, f)
case *Assign:
if node.Name != nil {
Walk(node.Name, f)
}
if node.Value != nil {
Walk(node.Value, f)
}
if node.Index != nil {
Walk(node.Index, f)
}
if node.Array != nil {
Walk(node.Array, f)
}
walkNilable(node.Name, f)
walkNilable(node.Value, f)
walkNilable(node.Index, f)
walkNilable(node.Array, f)
case *Redirect:
if node.N != nil {
Walk(node.N, f)
}
walkNilable(node.N, f)
Walk(node.Word, f)
if node.Hdoc != nil {
Walk(node.Hdoc, f)
}
walkNilable(node.Hdoc, f)
case *CallExpr:
walkList(node.Assigns, f)
walkList(node.Args, f)
Expand All @@ -70,9 +58,7 @@ func Walk(node Node, f func(Node) bool) {
walkComments(node.CondLast, f)
walkList(node.Then, f)
walkComments(node.ThenLast, f)
if node.Else != nil {
Walk(node.Else, f)
}
walkNilable(node.Else, f)
case *WhileClause:
walkList(node.Cond, f)
walkComments(node.CondLast, f)
Expand All @@ -86,15 +72,9 @@ func Walk(node Node, f func(Node) bool) {
Walk(node.Name, f)
walkList(node.Items, f)
case *CStyleLoop:
if node.Init != nil {
Walk(node.Init, f)
}
if node.Cond != nil {
Walk(node.Cond, f)
}
if node.Post != nil {
Walk(node.Post, f)
}
walkNilable(node.Init, f)
walkNilable(node.Cond, f)
walkNilable(node.Post, f)
case *BinaryCmd:
Walk(node.X, f)
Walk(node.Y, f)
Expand All @@ -112,19 +92,13 @@ func Walk(node Node, f func(Node) bool) {
walkComments(node.Last, f)
case *ParamExp:
Walk(node.Param, f)
if node.Index != nil {
Walk(node.Index, f)
}
walkNilable(node.Index, f)
if node.Repl != nil {
if node.Repl.Orig != nil {
Walk(node.Repl.Orig, f)
}
if node.Repl.With != nil {
Walk(node.Repl.With, f)
}
walkNilable(node.Repl.Orig, f)
walkNilable(node.Repl.With, f)
}
if node.Exp != nil && node.Exp.Word != nil {
Walk(node.Exp.Word, f)
if node.Exp != nil {
walkNilable(node.Exp.Word, f)
}
case *ArithmExp:
Walk(node.X, f)
Expand Down Expand Up @@ -174,25 +148,17 @@ func Walk(node Node, f func(Node) bool) {
}
Walk(&c, f)
}
if node.Index != nil {
Walk(node.Index, f)
}
if node.Value != nil {
Walk(node.Value, f)
}
walkNilable(node.Index, f)
walkNilable(node.Value, f)
case *ExtGlob:
Walk(node.Pattern, f)
case *ProcSubst:
walkList(node.Stmts, f)
walkComments(node.Last, f)
case *TimeClause:
if node.Stmt != nil {
Walk(node.Stmt, f)
}
walkNilable(node.Stmt, f)
case *CoprocClause:
if node.Name != nil {
Walk(node.Name, f)
}
walkNilable(node.Name, f)
Walk(node.Stmt, f)
case *LetClause:
walkList(node.Exprs, f)
Expand All @@ -206,6 +172,17 @@ func Walk(node Node, f func(Node) bool) {
f(nil)
}

type nilableNode interface {
Node
comparable // pointer nodes, which can be compared to nil
}

func walkNilable[N nilableNode](node N, f func(Node) bool) {
var zero N // nil
if node != zero {
Walk(node, f)
}
}
func walkList[N Node](list []N, f func(Node) bool) {
for _, node := range list {
Walk(node, f)
Expand Down

0 comments on commit aa946ad

Please sign in to comment.