package ast
import (
	
	
)
type Visitor interface {
	Visit(node Node) (w Visitor)
}
func [ Node]( Visitor,  []) {
	for ,  := range  {
		Walk(, )
	}
}
func ( Visitor,  Node) {
	if  = .Visit();  == nil {
		return
	}
	
	switch n := .(type) {
	
	case *Comment:
		
	case *CommentGroup:
		walkList(, .List)
	case *Field:
		if .Doc != nil {
			(, .Doc)
		}
		walkList(, .Names)
		if .Type != nil {
			(, .Type)
		}
		if .Tag != nil {
			(, .Tag)
		}
		if .Comment != nil {
			(, .Comment)
		}
	case *FieldList:
		walkList(, .List)
	
	case *BadExpr, *Ident, *BasicLit:
		
	case *Ellipsis:
		if .Elt != nil {
			(, .Elt)
		}
	case *FuncLit:
		(, .Type)
		(, .Body)
	case *CompositeLit:
		if .Type != nil {
			(, .Type)
		}
		walkList(, .Elts)
	case *ParenExpr:
		(, .X)
	case *SelectorExpr:
		(, .X)
		(, .Sel)
	case *IndexExpr:
		(, .X)
		(, .Index)
	case *IndexListExpr:
		(, .X)
		walkList(, .Indices)
	case *SliceExpr:
		(, .X)
		if .Low != nil {
			(, .Low)
		}
		if .High != nil {
			(, .High)
		}
		if .Max != nil {
			(, .Max)
		}
	case *TypeAssertExpr:
		(, .X)
		if .Type != nil {
			(, .Type)
		}
	case *CallExpr:
		(, .Fun)
		walkList(, .Args)
	case *StarExpr:
		(, .X)
	case *UnaryExpr:
		(, .X)
	case *BinaryExpr:
		(, .X)
		(, .Y)
	case *KeyValueExpr:
		(, .Key)
		(, .Value)
	
	case *ArrayType:
		if .Len != nil {
			(, .Len)
		}
		(, .Elt)
	case *StructType:
		(, .Fields)
	case *FuncType:
		if .TypeParams != nil {
			(, .TypeParams)
		}
		if .Params != nil {
			(, .Params)
		}
		if .Results != nil {
			(, .Results)
		}
	case *InterfaceType:
		(, .Methods)
	case *MapType:
		(, .Key)
		(, .Value)
	case *ChanType:
		(, .Value)
	
	case *BadStmt:
		
	case *DeclStmt:
		(, .Decl)
	case *EmptyStmt:
		
	case *LabeledStmt:
		(, .Label)
		(, .Stmt)
	case *ExprStmt:
		(, .X)
	case *SendStmt:
		(, .Chan)
		(, .Value)
	case *IncDecStmt:
		(, .X)
	case *AssignStmt:
		walkList(, .Lhs)
		walkList(, .Rhs)
	case *GoStmt:
		(, .Call)
	case *DeferStmt:
		(, .Call)
	case *ReturnStmt:
		walkList(, .Results)
	case *BranchStmt:
		if .Label != nil {
			(, .Label)
		}
	case *BlockStmt:
		walkList(, .List)
	case *IfStmt:
		if .Init != nil {
			(, .Init)
		}
		(, .Cond)
		(, .Body)
		if .Else != nil {
			(, .Else)
		}
	case *CaseClause:
		walkList(, .List)
		walkList(, .Body)
	case *SwitchStmt:
		if .Init != nil {
			(, .Init)
		}
		if .Tag != nil {
			(, .Tag)
		}
		(, .Body)
	case *TypeSwitchStmt:
		if .Init != nil {
			(, .Init)
		}
		(, .Assign)
		(, .Body)
	case *CommClause:
		if .Comm != nil {
			(, .Comm)
		}
		walkList(, .Body)
	case *SelectStmt:
		(, .Body)
	case *ForStmt:
		if .Init != nil {
			(, .Init)
		}
		if .Cond != nil {
			(, .Cond)
		}
		if .Post != nil {
			(, .Post)
		}
		(, .Body)
	case *RangeStmt:
		if .Key != nil {
			(, .Key)
		}
		if .Value != nil {
			(, .Value)
		}
		(, .X)
		(, .Body)
	
	case *ImportSpec:
		if .Doc != nil {
			(, .Doc)
		}
		if .Name != nil {
			(, .Name)
		}
		(, .Path)
		if .Comment != nil {
			(, .Comment)
		}
	case *ValueSpec:
		if .Doc != nil {
			(, .Doc)
		}
		walkList(, .Names)
		if .Type != nil {
			(, .Type)
		}
		walkList(, .Values)
		if .Comment != nil {
			(, .Comment)
		}
	case *TypeSpec:
		if .Doc != nil {
			(, .Doc)
		}
		(, .Name)
		if .TypeParams != nil {
			(, .TypeParams)
		}
		(, .Type)
		if .Comment != nil {
			(, .Comment)
		}
	case *BadDecl:
		
	case *GenDecl:
		if .Doc != nil {
			(, .Doc)
		}
		walkList(, .Specs)
	case *FuncDecl:
		if .Doc != nil {
			(, .Doc)
		}
		if .Recv != nil {
			(, .Recv)
		}
		(, .Name)
		(, .Type)
		if .Body != nil {
			(, .Body)
		}
	
	case *File:
		if .Doc != nil {
			(, .Doc)
		}
		(, .Name)
		walkList(, .Decls)
		
	case *Package:
		for ,  := range .Files {
			(, )
		}
	default:
		panic(fmt.Sprintf("ast.Walk: unexpected node type %T", ))
	}
	.Visit(nil)
}
type inspector func(Node) bool
func ( inspector) ( Node) Visitor {
	if () {
		return 
	}
	return nil
}
func ( Node,  func(Node) bool) {
	Walk(inspector(), )
}
func ( Node) iter.Seq[Node] {
	return func( func(Node) bool) {
		 := true
		Inspect(, func( Node) bool {
			if  != nil {
				
				 =  && ()
			}
			return 
		})
	}
}