URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [go/] [ast/] [walk.go] - Rev 747
Compare with Previous | Blame | View Log
// Copyright 2009 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 astimport "fmt"// A Visitor's Visit method is invoked for each node encountered by Walk.// If the result visitor w is not nil, Walk visits each of the children// of node with the visitor w, followed by a call of w.Visit(nil).type Visitor interface {Visit(node Node) (w Visitor)}// Helper functions for common node lists. They may be empty.func walkIdentList(v Visitor, list []*Ident) {for _, x := range list {Walk(v, x)}}func walkExprList(v Visitor, list []Expr) {for _, x := range list {Walk(v, x)}}func walkStmtList(v Visitor, list []Stmt) {for _, x := range list {Walk(v, x)}}func walkDeclList(v Visitor, list []Decl) {for _, x := range list {Walk(v, x)}}// TODO(gri): Investigate if providing a closure to Walk leads to// simpler use (and may help eliminate Inspect in turn).// Walk traverses an AST in depth-first order: It starts by calling// v.Visit(node); node must not be nil. If the visitor w returned by// v.Visit(node) is not nil, Walk is invoked recursively with visitor// w for each of the non-nil children of node, followed by a call of// w.Visit(nil).//func Walk(v Visitor, node Node) {if v = v.Visit(node); v == nil {return}// walk children// (the order of the cases matches the order// of the corresponding node types in ast.go)switch n := node.(type) {// Comments and fieldscase *Comment:// nothing to docase *CommentGroup:for _, c := range n.List {Walk(v, c)}case *Field:if n.Doc != nil {Walk(v, n.Doc)}walkIdentList(v, n.Names)Walk(v, n.Type)if n.Tag != nil {Walk(v, n.Tag)}if n.Comment != nil {Walk(v, n.Comment)}case *FieldList:for _, f := range n.List {Walk(v, f)}// Expressionscase *BadExpr, *Ident, *BasicLit:// nothing to docase *Ellipsis:if n.Elt != nil {Walk(v, n.Elt)}case *FuncLit:Walk(v, n.Type)Walk(v, n.Body)case *CompositeLit:if n.Type != nil {Walk(v, n.Type)}walkExprList(v, n.Elts)case *ParenExpr:Walk(v, n.X)case *SelectorExpr:Walk(v, n.X)Walk(v, n.Sel)case *IndexExpr:Walk(v, n.X)Walk(v, n.Index)case *SliceExpr:Walk(v, n.X)if n.Low != nil {Walk(v, n.Low)}if n.High != nil {Walk(v, n.High)}case *TypeAssertExpr:Walk(v, n.X)if n.Type != nil {Walk(v, n.Type)}case *CallExpr:Walk(v, n.Fun)walkExprList(v, n.Args)case *StarExpr:Walk(v, n.X)case *UnaryExpr:Walk(v, n.X)case *BinaryExpr:Walk(v, n.X)Walk(v, n.Y)case *KeyValueExpr:Walk(v, n.Key)Walk(v, n.Value)// Typescase *ArrayType:if n.Len != nil {Walk(v, n.Len)}Walk(v, n.Elt)case *StructType:Walk(v, n.Fields)case *FuncType:Walk(v, n.Params)if n.Results != nil {Walk(v, n.Results)}case *InterfaceType:Walk(v, n.Methods)case *MapType:Walk(v, n.Key)Walk(v, n.Value)case *ChanType:Walk(v, n.Value)// Statementscase *BadStmt:// nothing to docase *DeclStmt:Walk(v, n.Decl)case *EmptyStmt:// nothing to docase *LabeledStmt:Walk(v, n.Label)Walk(v, n.Stmt)case *ExprStmt:Walk(v, n.X)case *SendStmt:Walk(v, n.Chan)Walk(v, n.Value)case *IncDecStmt:Walk(v, n.X)case *AssignStmt:walkExprList(v, n.Lhs)walkExprList(v, n.Rhs)case *GoStmt:Walk(v, n.Call)case *DeferStmt:Walk(v, n.Call)case *ReturnStmt:walkExprList(v, n.Results)case *BranchStmt:if n.Label != nil {Walk(v, n.Label)}case *BlockStmt:walkStmtList(v, n.List)case *IfStmt:if n.Init != nil {Walk(v, n.Init)}Walk(v, n.Cond)Walk(v, n.Body)if n.Else != nil {Walk(v, n.Else)}case *CaseClause:walkExprList(v, n.List)walkStmtList(v, n.Body)case *SwitchStmt:if n.Init != nil {Walk(v, n.Init)}if n.Tag != nil {Walk(v, n.Tag)}Walk(v, n.Body)case *TypeSwitchStmt:if n.Init != nil {Walk(v, n.Init)}Walk(v, n.Assign)Walk(v, n.Body)case *CommClause:if n.Comm != nil {Walk(v, n.Comm)}walkStmtList(v, n.Body)case *SelectStmt:Walk(v, n.Body)case *ForStmt:if n.Init != nil {Walk(v, n.Init)}if n.Cond != nil {Walk(v, n.Cond)}if n.Post != nil {Walk(v, n.Post)}Walk(v, n.Body)case *RangeStmt:Walk(v, n.Key)if n.Value != nil {Walk(v, n.Value)}Walk(v, n.X)Walk(v, n.Body)// Declarationscase *ImportSpec:if n.Doc != nil {Walk(v, n.Doc)}if n.Name != nil {Walk(v, n.Name)}Walk(v, n.Path)if n.Comment != nil {Walk(v, n.Comment)}case *ValueSpec:if n.Doc != nil {Walk(v, n.Doc)}walkIdentList(v, n.Names)if n.Type != nil {Walk(v, n.Type)}walkExprList(v, n.Values)if n.Comment != nil {Walk(v, n.Comment)}case *TypeSpec:if n.Doc != nil {Walk(v, n.Doc)}Walk(v, n.Name)Walk(v, n.Type)if n.Comment != nil {Walk(v, n.Comment)}case *BadDecl:// nothing to docase *GenDecl:if n.Doc != nil {Walk(v, n.Doc)}for _, s := range n.Specs {Walk(v, s)}case *FuncDecl:if n.Doc != nil {Walk(v, n.Doc)}if n.Recv != nil {Walk(v, n.Recv)}Walk(v, n.Name)Walk(v, n.Type)if n.Body != nil {Walk(v, n.Body)}// Files and packagescase *File:if n.Doc != nil {Walk(v, n.Doc)}Walk(v, n.Name)walkDeclList(v, n.Decls)for _, g := range n.Comments {Walk(v, g)}// don't walk n.Comments - they have been// visited already through the individual// nodescase *Package:for _, f := range n.Files {Walk(v, f)}default:fmt.Printf("ast.Walk: unexpected node type %T", n)panic("ast.Walk")}v.Visit(nil)}type inspector func(Node) boolfunc (f inspector) Visit(node Node) Visitor {if f(node) {return f}return nil}// Inspect traverses an AST in depth-first order: It starts by calling// f(node); node must not be nil. If f returns true, Inspect invokes f// for all the non-nil children of node, recursively.//func Inspect(node Node, f func(Node) bool) {Walk(inspector(f), node)}
