1
0
mirror of https://github.com/go-task/task.git synced 2024-12-21 01:49:06 +02:00
task/vendor/mvdan.cc/sh/syntax/walk.go

222 lines
3.8 KiB
Go
Raw Normal View History

2017-04-24 14:47:10 +02:00
// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information
package syntax
import "fmt"
2017-07-06 01:46:05 +02:00
func walkStmts(sl StmtList, f func(Node) bool) {
for _, s := range sl.Stmts {
2017-04-24 14:47:10 +02:00
Walk(s, f)
}
for _, c := range sl.Last {
Walk(&c, f)
}
2017-04-24 14:47:10 +02:00
}
func walkWords(words []*Word, f func(Node) bool) {
for _, w := range words {
Walk(w, f)
}
}
// Walk traverses an AST in depth-first order: It starts by calling
// f(node); node must not be nil. If f returns true, Walk invokes f
// recursively for each of the non-nil children of node, followed by
// f(nil).
func Walk(node Node, f func(Node) bool) {
if !f(node) {
return
}
switch x := node.(type) {
case *File:
2017-07-06 01:46:05 +02:00
walkStmts(x.StmtList, f)
case *Comment:
2017-04-24 14:47:10 +02:00
case *Stmt:
for _, c := range x.Comments {
if c.Pos().After(x.Pos()) {
defer Walk(&c, f)
break
}
Walk(&c, f)
}
2017-04-24 14:47:10 +02:00
if x.Cmd != nil {
Walk(x.Cmd, f)
}
for _, r := range x.Redirs {
Walk(r, f)
}
case *Assign:
if x.Name != nil {
Walk(x.Name, f)
}
if x.Value != nil {
Walk(x.Value, f)
}
2017-06-04 21:06:04 +02:00
if x.Index != nil {
Walk(x.Index, f)
}
2017-05-17 19:49:27 +02:00
if x.Array != nil {
Walk(x.Array, f)
}
2017-04-24 14:47:10 +02:00
case *Redirect:
if x.N != nil {
Walk(x.N, f)
}
Walk(x.Word, f)
if x.Hdoc != nil {
Walk(x.Hdoc, f)
}
case *CallExpr:
2017-07-31 00:11:34 +02:00
for _, a := range x.Assigns {
Walk(a, f)
}
2017-04-24 14:47:10 +02:00
walkWords(x.Args, f)
case *Subshell:
2017-07-06 01:46:05 +02:00
walkStmts(x.StmtList, f)
2017-04-24 14:47:10 +02:00
case *Block:
2017-07-06 01:46:05 +02:00
walkStmts(x.StmtList, f)
2017-04-24 14:47:10 +02:00
case *IfClause:
2017-07-06 01:46:05 +02:00
walkStmts(x.Cond, f)
walkStmts(x.Then, f)
walkStmts(x.Else, f)
2017-04-24 14:47:10 +02:00
case *WhileClause:
2017-07-06 01:46:05 +02:00
walkStmts(x.Cond, f)
walkStmts(x.Do, f)
2017-04-24 14:47:10 +02:00
case *ForClause:
Walk(x.Loop, f)
2017-07-06 01:46:05 +02:00
walkStmts(x.Do, f)
2017-04-24 14:47:10 +02:00
case *WordIter:
Walk(x.Name, f)
2017-05-27 16:17:49 +02:00
walkWords(x.Items, f)
2017-04-24 14:47:10 +02:00
case *CStyleLoop:
if x.Init != nil {
Walk(x.Init, f)
}
if x.Cond != nil {
Walk(x.Cond, f)
}
if x.Post != nil {
Walk(x.Post, f)
}
case *BinaryCmd:
Walk(x.X, f)
Walk(x.Y, f)
case *FuncDecl:
Walk(x.Name, f)
Walk(x.Body, f)
case *Word:
for _, wp := range x.Parts {
Walk(wp, f)
}
case *Lit:
case *SglQuoted:
case *DblQuoted:
for _, wp := range x.Parts {
Walk(wp, f)
}
case *CmdSubst:
2017-07-06 01:46:05 +02:00
walkStmts(x.StmtList, f)
2017-04-24 14:47:10 +02:00
case *ParamExp:
2017-06-04 21:06:04 +02:00
Walk(x.Param, f)
2017-05-17 19:49:27 +02:00
if x.Index != nil {
Walk(x.Index, f)
2017-04-24 14:47:10 +02:00
}
if x.Repl != nil {
2017-05-27 16:17:49 +02:00
if x.Repl.Orig != nil {
Walk(x.Repl.Orig, f)
}
if x.Repl.With != nil {
Walk(x.Repl.With, f)
}
}
if x.Exp != nil && x.Exp.Word != nil {
2017-04-24 14:47:10 +02:00
Walk(x.Exp.Word, f)
}
case *ArithmExp:
2017-05-27 16:17:49 +02:00
Walk(x.X, f)
2017-04-24 14:47:10 +02:00
case *ArithmCmd:
2017-05-27 16:17:49 +02:00
Walk(x.X, f)
2017-04-24 14:47:10 +02:00
case *BinaryArithm:
Walk(x.X, f)
Walk(x.Y, f)
case *BinaryTest:
Walk(x.X, f)
Walk(x.Y, f)
case *UnaryArithm:
Walk(x.X, f)
case *UnaryTest:
Walk(x.X, f)
case *ParenArithm:
Walk(x.X, f)
case *ParenTest:
Walk(x.X, f)
case *CaseClause:
Walk(x.Word, f)
2017-05-27 16:17:49 +02:00
for _, ci := range x.Items {
2017-07-06 01:46:05 +02:00
Walk(ci, f)
2017-04-24 14:47:10 +02:00
}
for _, c := range x.Last {
Walk(&c, f)
}
2017-07-06 01:46:05 +02:00
case *CaseItem:
for _, c := range x.Comments {
if c.Pos().After(x.Pos()) {
defer Walk(&c, f)
break
}
Walk(&c, f)
}
2017-07-06 01:46:05 +02:00
walkWords(x.Patterns, f)
walkStmts(x.StmtList, f)
2017-04-24 14:47:10 +02:00
case *TestClause:
Walk(x.X, f)
case *DeclClause:
walkWords(x.Opts, f)
for _, a := range x.Assigns {
Walk(a, f)
}
case *ArrayExpr:
2017-05-27 16:17:49 +02:00
for _, el := range x.Elems {
Walk(el, f)
}
for _, c := range x.Last {
Walk(&c, f)
}
2017-05-27 16:17:49 +02:00
case *ArrayElem:
for _, c := range x.Comments {
if c.Pos().After(x.Pos()) {
defer Walk(&c, f)
break
}
Walk(&c, f)
}
2017-05-27 16:17:49 +02:00
if x.Index != nil {
Walk(x.Index, f)
}
Walk(x.Value, f)
2017-04-24 14:47:10 +02:00
case *ExtGlob:
Walk(x.Pattern, f)
case *ProcSubst:
2017-07-06 01:46:05 +02:00
walkStmts(x.StmtList, f)
2017-05-27 16:17:49 +02:00
case *TimeClause:
if x.Stmt != nil {
Walk(x.Stmt, f)
}
2017-04-24 14:47:10 +02:00
case *CoprocClause:
if x.Name != nil {
Walk(x.Name, f)
}
Walk(x.Stmt, f)
case *LetClause:
for _, expr := range x.Exprs {
Walk(expr, f)
}
default:
panic(fmt.Sprintf("syntax.Walk: unexpected node type %T", x))
}
f(nil)
}