mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-04 07:49:35 +00:00 
			
		
		
		
	* Changes to make vendored packages accept new home. * Fix go2idl to import vendored packages.
		
			
				
	
	
		
			211 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2012 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 ast_test
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"fmt"
 | 
						|
	"go/ast"
 | 
						|
	"go/format"
 | 
						|
	"go/parser"
 | 
						|
	"go/token"
 | 
						|
)
 | 
						|
 | 
						|
// This example demonstrates how to inspect the AST of a Go program.
 | 
						|
func ExampleInspect() {
 | 
						|
	// src is the input for which we want to inspect the AST.
 | 
						|
	src := `
 | 
						|
package p
 | 
						|
const c = 1.0
 | 
						|
var X = f(3.14)*2 + c
 | 
						|
`
 | 
						|
 | 
						|
	// Create the AST by parsing src.
 | 
						|
	fset := token.NewFileSet() // positions are relative to fset
 | 
						|
	f, err := parser.ParseFile(fset, "src.go", src, 0)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Inspect the AST and print all identifiers and literals.
 | 
						|
	ast.Inspect(f, func(n ast.Node) bool {
 | 
						|
		var s string
 | 
						|
		switch x := n.(type) {
 | 
						|
		case *ast.BasicLit:
 | 
						|
			s = x.Value
 | 
						|
		case *ast.Ident:
 | 
						|
			s = x.Name
 | 
						|
		}
 | 
						|
		if s != "" {
 | 
						|
			fmt.Printf("%s:\t%s\n", fset.Position(n.Pos()), s)
 | 
						|
		}
 | 
						|
		return true
 | 
						|
	})
 | 
						|
 | 
						|
	// output:
 | 
						|
	// src.go:2:9:	p
 | 
						|
	// src.go:3:7:	c
 | 
						|
	// src.go:3:11:	1.0
 | 
						|
	// src.go:4:5:	X
 | 
						|
	// src.go:4:9:	f
 | 
						|
	// src.go:4:11:	3.14
 | 
						|
	// src.go:4:17:	2
 | 
						|
	// src.go:4:21:	c
 | 
						|
}
 | 
						|
 | 
						|
// This example shows what an AST looks like when printed for debugging.
 | 
						|
func ExamplePrint() {
 | 
						|
	// src is the input for which we want to print the AST.
 | 
						|
	src := `
 | 
						|
package main
 | 
						|
func main() {
 | 
						|
	println("Hello, World!")
 | 
						|
}
 | 
						|
`
 | 
						|
 | 
						|
	// Create the AST by parsing src.
 | 
						|
	fset := token.NewFileSet() // positions are relative to fset
 | 
						|
	f, err := parser.ParseFile(fset, "", src, 0)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Print the AST.
 | 
						|
	ast.Print(fset, f)
 | 
						|
 | 
						|
	// output:
 | 
						|
	//      0  *ast.File {
 | 
						|
	//      1  .  Package: 2:1
 | 
						|
	//      2  .  Name: *ast.Ident {
 | 
						|
	//      3  .  .  NamePos: 2:9
 | 
						|
	//      4  .  .  Name: "main"
 | 
						|
	//      5  .  }
 | 
						|
	//      6  .  Decls: []ast.Decl (len = 1) {
 | 
						|
	//      7  .  .  0: *ast.FuncDecl {
 | 
						|
	//      8  .  .  .  Name: *ast.Ident {
 | 
						|
	//      9  .  .  .  .  NamePos: 3:6
 | 
						|
	//     10  .  .  .  .  Name: "main"
 | 
						|
	//     11  .  .  .  .  Obj: *ast.Object {
 | 
						|
	//     12  .  .  .  .  .  Kind: func
 | 
						|
	//     13  .  .  .  .  .  Name: "main"
 | 
						|
	//     14  .  .  .  .  .  Decl: *(obj @ 7)
 | 
						|
	//     15  .  .  .  .  }
 | 
						|
	//     16  .  .  .  }
 | 
						|
	//     17  .  .  .  Type: *ast.FuncType {
 | 
						|
	//     18  .  .  .  .  Func: 3:1
 | 
						|
	//     19  .  .  .  .  Params: *ast.FieldList {
 | 
						|
	//     20  .  .  .  .  .  Opening: 3:10
 | 
						|
	//     21  .  .  .  .  .  Closing: 3:11
 | 
						|
	//     22  .  .  .  .  }
 | 
						|
	//     23  .  .  .  }
 | 
						|
	//     24  .  .  .  Body: *ast.BlockStmt {
 | 
						|
	//     25  .  .  .  .  Lbrace: 3:13
 | 
						|
	//     26  .  .  .  .  List: []ast.Stmt (len = 1) {
 | 
						|
	//     27  .  .  .  .  .  0: *ast.ExprStmt {
 | 
						|
	//     28  .  .  .  .  .  .  X: *ast.CallExpr {
 | 
						|
	//     29  .  .  .  .  .  .  .  Fun: *ast.Ident {
 | 
						|
	//     30  .  .  .  .  .  .  .  .  NamePos: 4:2
 | 
						|
	//     31  .  .  .  .  .  .  .  .  Name: "println"
 | 
						|
	//     32  .  .  .  .  .  .  .  }
 | 
						|
	//     33  .  .  .  .  .  .  .  Lparen: 4:9
 | 
						|
	//     34  .  .  .  .  .  .  .  Args: []ast.Expr (len = 1) {
 | 
						|
	//     35  .  .  .  .  .  .  .  .  0: *ast.BasicLit {
 | 
						|
	//     36  .  .  .  .  .  .  .  .  .  ValuePos: 4:10
 | 
						|
	//     37  .  .  .  .  .  .  .  .  .  Kind: STRING
 | 
						|
	//     38  .  .  .  .  .  .  .  .  .  Value: "\"Hello, World!\""
 | 
						|
	//     39  .  .  .  .  .  .  .  .  }
 | 
						|
	//     40  .  .  .  .  .  .  .  }
 | 
						|
	//     41  .  .  .  .  .  .  .  Ellipsis: -
 | 
						|
	//     42  .  .  .  .  .  .  .  Rparen: 4:25
 | 
						|
	//     43  .  .  .  .  .  .  }
 | 
						|
	//     44  .  .  .  .  .  }
 | 
						|
	//     45  .  .  .  .  }
 | 
						|
	//     46  .  .  .  .  Rbrace: 5:1
 | 
						|
	//     47  .  .  .  }
 | 
						|
	//     48  .  .  }
 | 
						|
	//     49  .  }
 | 
						|
	//     50  .  Scope: *ast.Scope {
 | 
						|
	//     51  .  .  Objects: map[string]*ast.Object (len = 1) {
 | 
						|
	//     52  .  .  .  "main": *(obj @ 11)
 | 
						|
	//     53  .  .  }
 | 
						|
	//     54  .  }
 | 
						|
	//     55  .  Unresolved: []*ast.Ident (len = 1) {
 | 
						|
	//     56  .  .  0: *(obj @ 29)
 | 
						|
	//     57  .  }
 | 
						|
	//     58  }
 | 
						|
}
 | 
						|
 | 
						|
// This example illustrates how to remove a variable declaration
 | 
						|
// in a Go program while maintaining correct comment association
 | 
						|
// using an ast.CommentMap.
 | 
						|
func ExampleCommentMap() {
 | 
						|
	// src is the input for which we create the AST that we
 | 
						|
	// are going to manipulate.
 | 
						|
	src := `
 | 
						|
// This is the package comment.
 | 
						|
package main
 | 
						|
 | 
						|
// This comment is associated with the hello constant.
 | 
						|
const hello = "Hello, World!" // line comment 1
 | 
						|
 | 
						|
// This comment is associated with the foo variable.
 | 
						|
var foo = hello // line comment 2 
 | 
						|
 | 
						|
// This comment is associated with the main function.
 | 
						|
func main() {
 | 
						|
	fmt.Println(hello) // line comment 3
 | 
						|
}
 | 
						|
`
 | 
						|
 | 
						|
	// Create the AST by parsing src.
 | 
						|
	fset := token.NewFileSet() // positions are relative to fset
 | 
						|
	f, err := parser.ParseFile(fset, "src.go", src, parser.ParseComments)
 | 
						|
	if err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
 | 
						|
	// Create an ast.CommentMap from the ast.File's comments.
 | 
						|
	// This helps keeping the association between comments
 | 
						|
	// and AST nodes.
 | 
						|
	cmap := ast.NewCommentMap(fset, f, f.Comments)
 | 
						|
 | 
						|
	// Remove the first variable declaration from the list of declarations.
 | 
						|
	f.Decls = removeFirstVarDecl(f.Decls)
 | 
						|
 | 
						|
	// Use the comment map to filter comments that don't belong anymore
 | 
						|
	// (the comments associated with the variable declaration), and create
 | 
						|
	// the new comments list.
 | 
						|
	f.Comments = cmap.Filter(f).Comments()
 | 
						|
 | 
						|
	// Print the modified AST.
 | 
						|
	var buf bytes.Buffer
 | 
						|
	if err := format.Node(&buf, fset, f); err != nil {
 | 
						|
		panic(err)
 | 
						|
	}
 | 
						|
	fmt.Printf("%s", buf.Bytes())
 | 
						|
 | 
						|
	// output:
 | 
						|
	// // This is the package comment.
 | 
						|
	// package main
 | 
						|
	//
 | 
						|
	// // This comment is associated with the hello constant.
 | 
						|
	// const hello = "Hello, World!" // line comment 1
 | 
						|
	//
 | 
						|
	// // This comment is associated with the main function.
 | 
						|
	// func main() {
 | 
						|
	// 	fmt.Println(hello) // line comment 3
 | 
						|
	// }
 | 
						|
}
 | 
						|
 | 
						|
func removeFirstVarDecl(list []ast.Decl) []ast.Decl {
 | 
						|
	for i, decl := range list {
 | 
						|
		if gen, ok := decl.(*ast.GenDecl); ok && gen.Tok == token.VAR {
 | 
						|
			copy(list[i:], list[i+1:])
 | 
						|
			return list[:len(list)-1]
 | 
						|
		}
 | 
						|
	}
 | 
						|
	panic("variable declaration not found")
 | 
						|
}
 |