本文整理匯總了Golang中code/google/com/p/rog-go/exp/go/ast.Walk函數的典型用法代碼示例。如果您正苦於以下問題:Golang Walk函數的具體用法?Golang Walk怎麽用?Golang Walk使用的例子?那麽, 這裏精選的函數代碼示例或許可以為您提供幫助。
在下文中一共展示了Walk函數的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的Golang代碼示例。
示例1: findIdentifier
// findIdentifier looks for an identifier at byte-offset searchpos
// inside the parsed source represented by node.
// If it is part of a selector expression, it returns
// that expression rather than the identifier itself.
//
// As a special case, if it finds an import
// spec, it returns ImportSpec.
//
func findIdentifier(f *ast.File, searchpos int) ast.Node {
ec := make(chan ast.Node)
go func() {
visit := func(n ast.Node) bool {
var startPos token.Pos
switch n := n.(type) {
case *ast.Ident:
startPos = n.NamePos
case *ast.SelectorExpr:
startPos = n.Sel.NamePos
case *ast.ImportSpec:
startPos = n.Pos()
default:
return true
}
start := types.FileSet.Position(startPos).Offset
end := start + int(n.End()-startPos)
if start <= searchpos && searchpos <= end {
ec <- n
runtime.Goexit()
}
return true
}
ast.Walk(FVisitor(visit), f)
ec <- nil
}()
ev := <-ec
if ev == nil {
fail("no identifier found")
}
return ev
}
示例2: findIdentifier
// findIdentifier looks for an identifier at byte-offset searchpos
// inside the parsed source represented by node.
// If it is part of a selector expression, it returns
// that expression rather than the identifier itself.
//
// As a special case, if it finds an import
// spec, it returns ImportSpec.
//
func findIdentifier(f *ast.File, searchpos int) ast.Node {
ec := make(chan ast.Node)
found := func(startPos, endPos token.Pos) bool {
start := types.FileSet.Position(startPos).Offset
end := start + int(endPos-startPos)
return start <= searchpos && searchpos <= end
}
go func() {
var visit func(ast.Node) bool
visit = func(n ast.Node) bool {
var startPos token.Pos
switch n := n.(type) {
default:
return true
case *ast.Ident:
startPos = n.NamePos
case *ast.SelectorExpr:
startPos = n.Sel.NamePos
case *ast.ImportSpec:
startPos = n.Pos()
case *ast.StructType:
// If we find an anonymous bare field in a
// struct type, its definition points to itself,
// but we actually want to go elsewhere,
// so assume (dubiously) that the expression
// works globally and return a new node for it.
for _, field := range n.Fields.List {
if field.Names != nil {
continue
}
t := field.Type
if pt, ok := field.Type.(*ast.StarExpr); ok {
t = pt.X
}
if id, ok := t.(*ast.Ident); ok {
if found(id.NamePos, id.End()) {
ec <- parseExpr(f.Scope, id.Name)
runtime.Goexit()
}
}
}
return true
}
if found(startPos, n.End()) {
ec <- n
runtime.Goexit()
}
return true
}
ast.Walk(FVisitor(visit), f)
ec <- nil
}()
ev := <-ec
if ev == nil {
fail("no identifier found")
}
return ev
}
示例3: ScanCmd
func ScanCmd(args []string) (err error) {
ScanAllForImports(LocalRoot)
for _, path := range args {
pkg := LocalImporter(path)
ast.Walk(DepthWalker(0), pkg)
}
return
}
示例4: containsNode
// constainsNode returns true if x is found somewhere
// inside node.
func containsNode(node, x ast.Node) (found bool) {
ast.Walk(funcVisitor(func(n ast.Node) bool {
if !found {
found = n == x
}
return !found
}),
node)
return
}
示例5: GetUniqueIdent
func GetUniqueIdent(files []*ast.File, candidate string) (id string) {
ic := make(IdentCollector)
for _, file := range files {
ast.Walk(ic, file)
}
id = candidate
for i := 0; ic[id]; i++ {
id = fmt.Sprintf("%s_%d", candidate, i)
}
return
}
示例6: CollectNameObjs
func (this *SingleMover) CollectNameObjs(name string) (found bool) {
for _, file := range this.pkg.Files {
fdl := DeclFinder{oldname: name}
ast.Walk(&fdl, file)
if fdl.Obj != nil {
found = true
this.moveNodes[fdl.Node] = fdl.Obj
mf := MethodFinder{
Receiver: fdl.Obj,
NodeObjs: make(map[ast.Node]*ast.Object),
}
ast.Walk(&mf, this.pkg)
for node, obj := range mf.NodeObjs {
this.moveNodes[node] = obj
}
}
}
return
}
示例7: Visit
func (this ListImportWalker) Visit(node ast.Node) ast.Visitor {
switch n := node.(type) {
case *ast.SelectorExpr:
ast.Walk(this, n.X)
//skip n.Sel, we don't need to import for it
return nil
case *ast.Ident:
obj, typ := types.ExprType(n, LocalImporter)
if is, ok := typ.Node.(*ast.ImportSpec); ok {
this[obj] = is
}
}
return this
}
示例8: TestOneFile
func TestOneFile(t *testing.T) {
code, offsetMap := translateSymbols(testCode)
//fmt.Printf("------------------- {%s}\n", code)
f, err := parser.ParseFile(FileSet, "xx.go", code, 0, ast.NewScope(parser.Universe))
if err != nil {
t.Fatalf("parse failed: %v", err)
}
v := make(identVisitor)
go func() {
ast.Walk(v, f)
close(v)
}()
for e := range v {
testExpr(t, FileSet, e, offsetMap)
}
}
示例9: Visit
func (v identVisitor) Visit(n ast.Node) ast.Visitor {
switch n := n.(type) {
case *ast.Ident:
if strings.HasPrefix(n.Name, prefix) {
v <- n
}
return nil
case *ast.SelectorExpr:
ast.Walk(v, n.X)
if strings.HasPrefix(n.Sel.Name, prefix) {
v <- n
}
return nil
}
return v
}
示例10: ScanForImports
//Look at the imports, and build up ImportedBy
func ScanForImports(path string) (err error) {
sourcefiles, _ := filepath.Glob(filepath.Join(path, "*.go"))
dirpkgs, err := parser.ParseFiles(AllSourceTops, sourcefiles, parser.ImportsOnly)
if err != nil {
fmt.Println(err)
}
//take the first non-main. otherwise, main is ok.
var prime *ast.Package
for name, pkg := range dirpkgs {
prime = pkg
if name != "main" {
break
}
}
if prime == nil {
return
}
PackageTops[path] = prime
is := make(ImportScanner)
ast.Walk(is, prime)
if v, ok := is["."]; !v && ok {
return MakeErr("gorf can not deal with unnamed import in '%s'", path)
}
for path, _ := range is {
if strings.HasPrefix(path, ".") {
return MakeErr("gorf can not deal with relative import in '%s'", path)
}
}
for imp := range is {
ImportedBy[imp] = append(ImportedBy[imp], path)
}
return
}
示例11: MoveCmd
func MoveCmd(args []string) (err error) {
if len(args) < 2 {
return MakeErr("Usage: gorf [flags] move <old path> <new path> [<name>+]")
}
oldpath, newpath := filepath.Clean(args[0]), filepath.Clean(args[1])
if oldpath == newpath {
return MakeErr("Old path and new path are the same")
}
err = ScanAllForImports(LocalRoot)
if err != nil {
return
}
PreloadImportedBy(oldpath)
defer func() {
if err != nil {
UndoCmd([]string{})
}
}()
if PackageTops[oldpath] == nil {
return MakeErr("Old path %s has no local package", oldpath)
}
if PackageTops[newpath] != nil {
return MakeErr("New path %s already has a package (did you mean to merge?)", newpath)
}
pkg := LocalImporter(oldpath)
if len(args) >= 3 {
err = MoveSingle(oldpath, newpath, args[2:])
return
}
os.MkdirAll(filepath.Join(LocalRoot, newpath), 0755)
for fpath := range pkg.Files {
_, base := filepath.Split(fpath)
npath := filepath.Join(LocalRoot, newpath, base)
_ = npath
err = MoveSource(fpath, npath)
if err != nil {
return
}
}
for _, ip := range ImportedBy[QuotePath(oldpath)] {
ipkg := LocalImporter(ip)
for fpath, file := range ipkg.Files {
pcw := PathChangeWalker{OldPath: oldpath, NewPath: newpath}
ast.Walk(&pcw, file)
if pcw.Updated {
err = RewriteSource(fpath, file)
if err != nil {
return
}
}
}
}
return
}
示例12: checkExprs
func checkExprs(t *testing.T, pkg *ast.File, importer Importer) {
var visit astVisitor
stopped := false
visit = func(n ast.Node) bool {
if stopped {
return false
}
mustResolve := false
var e ast.Expr
switch n := n.(type) {
case *ast.ImportSpec:
// If the file imports a package to ".", abort
// because we don't support that (yet).
if n.Name != nil && n.Name.Name == "." {
stopped = true
return false
}
return true
case *ast.FuncDecl:
// add object for init functions
if n.Recv == nil && n.Name.Name == "init" {
n.Name.Obj = ast.NewObj(ast.Fun, "init")
}
return true
case *ast.Ident:
if n.Name == "_" {
return false
}
e = n
mustResolve = true
case *ast.KeyValueExpr:
// don't try to resolve the key part of a key-value
// because it might be a map key which doesn't
// need resolving, and we can't tell without being
// complicated with types.
ast.Walk(visit, n.Value)
return false
case *ast.SelectorExpr:
ast.Walk(visit, n.X)
e = n
mustResolve = true
case *ast.File:
for _, d := range n.Decls {
ast.Walk(visit, d)
}
return false
case ast.Expr:
e = n
default:
return true
}
defer func() {
if err := recover(); err != nil {
t.Fatalf("panic (%v) on %T", err, e)
//t.Fatalf("panic (%v) on %v at %v\n", err, e, FileSet.Position(e.Pos()))
}
}()
obj, _ := ExprType(e, importer)
if obj == nil && mustResolve {
t.Errorf("no object for %v(%p, %T) at %v\n", e, e, e, FileSet.Position(e.Pos()))
}
return false
}
ast.Walk(visit, pkg)
}
示例13: MoveSingle
func MoveSingle(oldpath, newpath string, names []string) (err error) {
for _, name := range names {
if !IsLegalIdentifier(name) {
return MakeErr("Name %s is not a legal identifier", name)
}
}
var sm SingleMover
pkg := LocalImporter(oldpath)
sm.pkg = pkg
sm.oldpath = oldpath
sm.newpath = newpath
moveNodes := make(map[ast.Node]*ast.Object)
sm.moveNodes = moveNodes
moveObjs := make(map[*ast.Object]ast.Node)
sm.moveObjs = moveObjs
allObjs := make(AllDeclFinder)
sm.allObjs = allObjs
//get all top level decl objs
ast.Walk(allObjs, pkg)
//find the nodes we want to move
for _, name := range names {
if !sm.CollectNameObjs(name) {
return MakeErr("Unable to find %s in '%s'", name, oldpath)
}
}
for node, obj := range moveNodes {
moveObjs[obj] = node
}
//the objs in remainingObjs are not being moved to the new package
remainingObjs := make(map[*ast.Object]bool)
sm.remainingObjs = remainingObjs
for obj := range sm.allObjs {
if _, ok := sm.moveObjs[obj]; !ok {
sm.remainingObjs[obj] = true
}
}
//get a list of objects that are unexported (and therefore if they
//are referenced elsewhere, the move cannot happen)
sm.unexportedObjs = make(map[*ast.Object]bool)
sm.CollectUnexportedObjs()
err = sm.CreateNewSource()
if err != nil {
return
}
//identify locations in pkg source files that need to now change
err = sm.RemoveUpdatePkg()
if err != nil {
return
}
//make changes in packages that import this one
err = sm.UpdateOther()
if err != nil {
return
}
return
}
示例14: PkgCmd
func PkgCmd(args []string) (err error) {
if len(args) != 2 {
return MakeErr("Usage: gorf [flags] pkg <path> <new name>")
}
path, newname := filepath.Clean(args[0]), args[1]
if !IsLegalIdentifier(newname) {
return MakeErr("New name %s is not a legal identifier", newname)
}
err = ScanAllForImports(LocalRoot)
if err != nil {
return
}
PreloadImportedBy(path)
defer func() {
if err != nil {
UndoCmd([]string{})
}
}()
if PackageTops[path] == nil {
return MakeErr("No local package found in %s", path)
}
pkg := LocalImporter(path)
oldname := pkg.Name
for fpath, file := range pkg.Files {
file.Name.Name = newname
err = RewriteSource(fpath, file)
if err != nil {
return
}
}
for _, ip := range ImportedBy[QuotePath(path)] {
ipkg := LocalImporter(ip)
if ipkg == nil {
return MakeErr("Problem getting package in %s", ip)
}
for fpath, file := range ipkg.Files {
uniqueName := GetUniqueIdent([]*ast.File{file}, newname)
if uniqueName != newname {
fmt.Printf("In %s: possible conflict with %s, using %s instead\n", fpath, newname, uniqueName)
}
pc := PkgChanger{
path: path,
oldname: oldname,
newname: uniqueName,
pkgname: newname,
}
ast.Walk(&pc, file)
if pc.Updated {
RewriteSource(fpath, file)
}
}
}
return
}
示例15: RemoveUpdatePkg
func (this *SingleMover) RemoveUpdatePkg() (err error) {
for fpath, file := range this.pkg.Files {
urw := ReferenceWalker{
UnexportedObjs: this.unexportedObjs,
SkipNodes: this.moveNodes,
MoveObjs: this.moveObjs,
SkipNodeParents: make(map[ast.Node]ast.Node),
GoodReferenceParents: make(map[ast.Node]ast.Node),
BadReferences: new([]ast.Node),
}
ast.Walk(&urw, file)
if len(*urw.BadReferences) != 0 {
fmt.Printf("Cannot move some objects:\n")
for node := range this.moveNodes {
printer.Fprint(os.Stdout, token.NewFileSet(), node)
fmt.Println()
}
fmt.Println("Unexported objects referenced:")
for _, node := range *urw.BadReferences {
position := AllSources.Position(node.Pos())
fmt.Printf("At %v ", position)
printer.Fprint(os.Stdout, token.NewFileSet(), node)
fmt.Println()
}
return MakeErr("Objects to be moved in '%s' contains unexported objects referenced elsewhere in the package", this.oldpath)
}
removedStuff := false
// remove the old definitions
for node, parent := range urw.SkipNodeParents {
removedStuff = true
//fmt.Printf("%T %v\n", parent, parent)
switch pn := parent.(type) {
case *ast.File:
for i, n := range pn.Decls {
if n == node {
if len(pn.Decls) > 1 {
pn.Decls[i], pn.Decls[len(pn.Decls)-1] = pn.Decls[len(pn.Decls)-1], pn.Decls[i]
}
pn.Decls = pn.Decls[:len(pn.Decls)-1]
break
}
}
case *ast.GenDecl:
for i, n := range pn.Specs {
if n == node {
if pn.Lparen == 0 {
pn.Lparen = n.Pos()
pn.Rparen = n.End()
}
if len(pn.Specs) > 1 {
pn.Specs[i], pn.Specs[len(pn.Specs)-1] = pn.Specs[len(pn.Specs)-1], pn.Specs[i]
}
pn.Specs = pn.Specs[:len(pn.Specs)-1]
break
}
}
default:
return MakeErr("Unanticipated parent type: %T", pn)
}
}
//strip out imports that are unnecessary because things are no longer here
if removedStuff {
for _, file := range this.pkg.Files {
iuc := make(ImportUseCollector)
ast.Walk(iuc, file)
ast.Walk(ImportFilterWalker(iuc), file)
}
}
//if this file refernces things that are moving, import the new package
if len(urw.GoodReferenceParents) != 0 {
if this.referenceBack {
return MakeErr("Moving objects from %s would create a cycle", this.oldpath)
}
newpkgname := GetUniqueIdent([]*ast.File{file}, this.pkg.Name)
//construct the import
is := &ast.ImportSpec{
Name: &ast.Ident{Name: newpkgname},
Path: &ast.BasicLit{
Kind: token.STRING,
Value: QuotePath(this.newpath),
},
}
gd := &ast.GenDecl{
Tok: token.IMPORT,
Specs: []ast.Spec{is},
}
//stick it in there
file.Decls = append([]ast.Decl{gd}, file.Decls...)
//.........這裏部分代碼省略.........